Hash join: Difference between revisions
Content added Content deleted
(→{{header|Rust}}: update and genericize) |
|||
Line 2,505: | Line 2,505: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
<lang rust>use std::collections::HashMap; |
<lang rust>use std::collections::HashMap; |
||
use std::hash::Hash; |
|||
// If you know one of the tables is smaller, it is best to make it the second parameter. |
|||
fn hash_join<A, B, K>(first: &[(K, A)], second: &[(K, B)]) -> Vec<(A, K, B)> |
|||
where |
|||
K: Hash + Eq + Copy, |
|||
A: Copy, |
|||
B: Copy, |
|||
{ |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
let table_b = vec![ |
|||
("Jonah", "Whales"), ("Jonah", "Spiders"), ("Alan", "Ghosts"), |
|||
("Alan", "Zombies"), ("Glory", "Buffy") |
|||
⚫ | |||
// hash phase |
// hash phase |
||
for &(key, val_a) in second { |
|||
⚫ | |||
// collect all values by their keys, appending new ones to each existing entry |
|||
for (i, a) in table_a.iter().enumerate() { |
|||
hash_map.entry(key).or_insert_with(Vec::new).push(val_a); |
|||
} |
} |
||
let mut result = Vec::new(); |
|||
// join phase |
// join phase |
||
for |
for &(key, val_b) in first { |
||
if let Some(vals) = |
if let Some(vals) = hash_map.get(&key) { |
||
let tuples = vals.iter().map(|&val_a| (val_b, key, val_a)); |
|||
result.extend(tuples); |
|||
⚫ | |||
⚫ | |||
} |
} |
||
} |
} |
||
result |
|||
} |
} |
||
⚫ | |||
⚫ | |||
let table1 = [("Jonah", 27), ("Alan", 18), ("Glory", 28), ("Popeye", 18), ("Alan", 28)]; |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
let result = hash_join(&table1, &table2); |
|||
println!("Age | Character Name | Nemesis"); |
|||
println!("----|----------------|--------"); |
|||
for (age, name, nemesis) in result { |
|||
⚫ | |||
⚫ | |||
⚫ | |||
{{out}} |
{{out}} |
||
<pre>Age | Character Name | Nemesis |
|||
<pre> |
|||
----|----------------|-------- |
|||
(27, "Jonah") ("Jonah", "Whales") |
|||
27 | Jonah | Whales |
|||
27 | Jonah | Spiders |
|||
(18, "Alan") ("Alan", "Ghosts") |
|||
18 | Alan | Ghosts |
|||
18 | Alan | Zombies |
|||
⚫ | |||
(28, "Alan") ("Alan", "Zombies") |
|||
28 | Alan | Ghosts |
|||
(28, "Glory") ("Glory", "Buffy") |
|||
28 | Alan | Zombies</pre> |
|||
</pre> |
|||
=={{header|Scala}}== |
=={{header|Scala}}== |