Hash join: Difference between revisions

Content added Content deleted
(Added PicoLisp)
Line 973: Line 973:
[[28, Alan], [Alan, Zombies]]
[[28, Alan], [Alan, Zombies]]
[[28, Glory], [Glory, Buffy]]</pre>
[[28, Glory], [Glory, Buffy]]</pre>


=={{header|JavaScript}}==
===ES6===

<lang JavaScript>(() => {
'use strict';

// hashJoin :: [Dict] -> [Dict] -> String -> [Dict]
let hashJoin = (tblA, tblB, strJoin) => {

let [jA, jB] = strJoin.split('='),
M = tblB.reduce((a, x) => {
let id = x[jB];
return (
a[id] ? a[id].push(x) : a[id] = [x],
a
);
}, {});

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

// dictConcat :: Dict -> Dict -> Dict
dictConcat = (dctA, dctB) => {
let 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, {}
)
);
};


// TEST
let lstA = [
{ age: 27, name: 'Jonah' },
{ age: 18, name: 'Alan' },
{ age: 28, name: 'Glory' },
{ age: 18, name: 'Popeye' },
{ age: 28, name: 'Alan' }
],
lstB = [
{ character: 'Jonah', nemesis: 'Whales' },
{ character: 'Jonah', nemesis: 'Spiders' },
{ character: 'Alan', nemesis: 'Ghosts' },
{ character:'Alan', nemesis: 'Zombies' },
{ character: 'Glory', nemesis: 'Buffy' },
{ character: 'Bob', nemesis: 'foo' }
];

return hashJoin(lstA, lstB, 'name=character');
})();
</lang>

{{Out}}
<pre>[{"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"}]</pre>


=={{header|jq}}==
=={{header|jq}}==