Files
freeCodeCamp/curriculum/challenges/ukrainian/22-rosetta-code/rosetta-code-challenges/hash-join.md
2024-02-19 19:27:27 -06:00

11 KiB
Raw Blame History

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
5956795bc9e2c415eb244de1 Хеш-об’єднання 1 302284 hash-join

--description--

Внутрішнє об’єднання — це операція, яка об’єднує дві таблиці даних в одну таблицю на основі відповідних значень стовпців. Найпростіший спосіб реалізації цієї операції — алгоритм об’єднання вкладеними циклами, але більш масштабований альтернативний варіант — це алгоритм хеш-об’єднання.

Алгоритм «хеш-об’єднання» складається з двох кроків:

  1. Етап хешування: створіть мультивідображення з однієї з двох таблиць, мапуючи значення з кожного стовпця до всіх рядків, які містять його.
    • Мультивідображення має підтримувати пошук на основі хешу, що масштабується краще, ніж простий лінійний пошук, оскільки це суть цього алгоритму.
    • В ідеальні потрібно створити мультивідображення для меншої таблиці, щоб мінімізувати час створення і розмір пам’яті.
  2. Етап об’єднання: проскануйте іншу таблицю та знайдіть рядки, які збігаються, глянувши на мультивідображення, створене раніше.

В псевдокоді алгоритм буде виражений наступним чином:

let A = перша вхідна таблиця (в ідеалі та, що більша)
let B = друга вхідна таблиця (в ідеалі та, що менша)
let jA = ID стовпця до об’єднання таблиці A
let jB = ID стовпця до об’єднання таблиці B
let MB = мультивідображення для мапування значень до декількох рядків таблиці B (спочатку порожня)
let C = вихідна таблиця (спочатку порожня)
for each рядок b в таблиці B:
  place b в мультивідображенні MB під ключем b(jB)
for each рядок a в таблиці A:
  for each рядок b в мультивідображенні MB під ключем a(jA):
    let c = об’єднання рядків a та b
    place рядок c в таблиці C

--instructions--

Реалізуйте алгоритм «хеш-об’єднання» як функцію та продемонструйте, що він проходить тестовий випадок вище. Функція має приймати два масиви об’єктів і повернути масив об’єднаних об’єктів.

Вхідні дані

A =
Age Name
27 Jonah
18 Alan
28 Glory
18 Popeye
28 Alan
B =
Character Nemesis
Jonah Whales
Jonah Spiders
Alan Ghosts
Alan Zombies
Glory Buffy
jA = Name (тобто стовпчик 1) jB = Character (тобто стовпчик 0)

Вихідні дані

A_age A_name B_character B_nemesis
27 Jonah Jonah Whales
27 Jonah Jonah Spiders
18 Alan Alan Ghosts
18 Alan Alan Zombies
28 Glory Glory Buffy
28 Alan Alan Ghosts
28 Alan Alan Zombies

Порядок рядків у вихідній таблиці не є важливим.

--hints--

hashJoin має бути функцією.

assert(typeof hashJoin === 'function');

hashJoin([{ age: 27, name: "Jonah" }, { age: 18, name: "Alan" }, { age: 28, name: "Glory" }, { age: 18, name: "Popeye" }, { age: 28, name: "Alan" }], [{ character: "Jonah", nemesis: "Whales" }, { character: "Jonah", nemesis: "Spiders" }, { character: "Alan", nemesis: "Ghosts" }, { character:"Alan", nemesis: "Zombies" }, { character: "Glory", nemesis: "Buffy" }, { character: "Bob", nemesis: "foo" }]) має повернути [{"A_age": 27,"A_name": "Jonah", "B_character": "Jonah", "B_nemesis": "Whales"}, {"A_age": 27,"A_name": "Jonah", "B_character": "Jonah", "B_nemesis": "Spiders"}, {"A_age": 18,"A_name": "Alan", "B_character": "Alan", "B_nemesis": "Ghosts"}, {"A_age": 18,"A_name": "Alan", "B_character": "Alan", "B_nemesis": "Zombies"}, {"A_age": 28,"A_name": "Glory", "B_character": "Glory", "B_nemesis": "Buffy"}, {"A_age": 28,"A_name": "Alan", "B_character": "Alan", "B_nemesis": "Ghosts"}, {"A_age": 28,"A_name": "Alan", "B_character": "Alan", "B_nemesis": "Zombies"}]

assert.deepEqual(hashJoin(hash1, hash2), res);

--seed--

--after-user-code--

const hash1 = [
    { age: 27, name: 'Jonah' },
    { age: 18, name: 'Alan' },
    { age: 28, name: 'Glory' },
    { age: 18, name: 'Popeye' },
    { age: 28, name: 'Alan' }
];

const hash2 = [
    { character: 'Jonah', nemesis: 'Whales' },
    { character: 'Jonah', nemesis: 'Spiders' },
    { character: 'Alan', nemesis: 'Ghosts' },
    { character: 'Alan', nemesis: 'Zombies' },
    { character: 'Glory', nemesis: 'Buffy' },
    { character: 'Bob', nemesis: 'foo' }
];

const res = [
    { A_age: 27, A_name: 'Jonah', B_character: 'Jonah', B_nemesis: 'Whales' },
    { A_age: 27, A_name: 'Jonah', B_character: 'Jonah', B_nemesis: 'Spiders' },
    { A_age: 18, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Ghosts' },
    { A_age: 18, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Zombies' },
    { A_age: 28, A_name: 'Glory', B_character: 'Glory', B_nemesis: 'Buffy' },
    { A_age: 28, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Ghosts' },
    { A_age: 28, A_name: 'Alan', B_character: 'Alan', B_nemesis: 'Zombies' }
];

const bench1 = [{ name: 'u2v7v', num: 1 }, { name: 'n53c8', num: 10 }, { name: 'oysce', num: 9 }, { name: '0mto2s', num: 1 }, { name: 'vkh5id', num: 4 }, { name: '5od0cf', num: 8 }, { name: 'uuulue', num: 10 }, { name: '3rgsbi', num: 9 }, { name: 'kccv35r', num: 4 }, { name: '80un74', num: 9 }, { name: 'h4pp3', num: 6 }, { name: '51bit', num: 7 }, { name: 'j9ndf', num: 8 }, { name: 'vf3u1', num: 10 }, { name: 'g0bw0om', num: 10 }, { name: 'j031x', num: 7 }, { name: 'ij3asc', num: 9 }, { name: 'byv83y', num: 8 }, { name: 'bjzp4k', num: 4 }, { name: 'f3kbnm', num: 10 }];
const bench2 = [{ friend: 'o8b', num: 8 }, { friend: 'ye', num: 2 }, { friend: '32i', num: 5 }, { friend: 'uz', num: 3 }, { friend: 'a5k', num: 4 }, { friend: 'uad', num: 7 }, { friend: '3w5', num: 10 }, { friend: 'vw', num: 10 }, { friend: 'ah', num: 4 }, { friend: 'qv', num: 7 }, { friend: 'ozv', num: 2 }, { friend: '9ri', num: 10 }, { friend: '7nu', num: 4 }, { friend: 'w3', num: 9 }, { friend: 'tgp', num: 8 }, { friend: 'ibs', num: 1 }, { friend: 'ss7', num: 6 }, { friend: 'g44', num: 9 }, { friend: 'tab', num: 9 }, { friend: 'zem', num: 10 }];

--seed-contents--

function hashJoin(hash1, hash2) {

  return [];
}

--solutions--

function hashJoin(hash1, hash2) {
  const hJoin = (tblA, tblB, strJoin) => {
    const [jA, jB] = strJoin.split('=');
    const M = tblB.reduce((a, x) => {
      const id = x[jB];
      return (
        a[id] ? a[id].push(x) : (a[id] = [x]),
        a
      );
    }, {});

    return tblA.reduce((a, x) => {
      const match = M[x[jA]];
      return match ? (
                a.concat(match.map(row => dictConcat(x, row)))
            ) : a;
    }, []);
  };

  const dictConcat = (dctA, dctB) => {
    const ok = Object.keys;
    return ok(dctB).reduce(
            (a, k) => (a[`B_${k}`] = dctB[k]) && a,
            ok(dctA).reduce(
                (a, k) => (a[`A_${k}`] = dctA[k]) && a, {}
            )
        );
  };

  return hJoin(hash1, hash2, 'name=character');
}