Hash join: Difference between revisions

Content added Content deleted
(Added zkl)
Line 989: Line 989:
<pre>$ txr hash-join.txr
<pre>$ txr hash-join.txr
(((27 Jonah) (Jonah Whales)) ((27 Jonah) (Jonah Spiders)) ((18 Alan) (Alan Ghosts)) ((28 Alan) (Alan Ghosts)) ((18 Alan) (Alan Zombies)) ((28 Alan) (Alan Zombies)) ((28 Glory) (Glory Buffy)))</pre>
(((27 Jonah) (Jonah Whales)) ((27 Jonah) (Jonah Spiders)) ((18 Alan) (Alan Ghosts)) ((28 Alan) (Alan Ghosts)) ((18 Alan) (Alan Zombies)) ((28 Alan) (Alan Zombies)) ((28 Glory) (Glory Buffy)))</pre>

=={{header|zkl}}==
Join two tables by hashing on the common key (name). The resulting join is the intersection of the two tables.
<lang zkl>ageName:=T(27,"Jonah", 18,"Alan", 28,"Glory", 18,"Popeye", 28,"Alan");
nameNemesis:=T("Jonah","Whales", "Jonah","Spiders", "Alan","Ghosts",
"Alan","Zombies", "Glory","Buffy");

fcn addAN(age,name,d){ // keys are names, values are ( (age,...),() )
if (r:=d.find(name)) d[name] = T(r[0].append(age),r[1]);
else d.add(name,T(T(age),T));
d // return d so pump will use that as result for assignment
}
fcn addNN(name,nemesis,d){ // values-->( (age,age...), (nemesis,...) )
if (r:=d.find(name)){
ages,nemesises := r;
d[name] = T(ages,nemesises.append(nemesis));
}
}
// (Void.Read,1) --> take existing i, read next one, pass both to next function
var d=ageName.pump(Void,T.fp(Void.Read,1),T(addAN,Dictionary()));
nameNemesis.pump(Void,T.fp(Void.Read,1),T(addNN,d));

d.println(); // the union of the two tables
d.keys.sort().pump(Console.println,'wrap(name){ //pretty print the join
val:=d[name]; if (not val[1])return(Void.Skip);
String(name,":",d[name][1].concat(","));
})
</lang>
zkl Dictionaries only have one key
<pre>
D(Popeye:L(L(18),L()),Glory:L(L(28),L("Buffy")),
Jonah:L(L(27),L("Whales","Spiders")),Alan:L(L(18,28),L("Ghosts","Zombies")))
Alan:Ghosts,Zombies
Glory:Buffy
Jonah:Whales,Spiders
</pre>