June 2018 Update
This commit is contained in:
parent
ba8067c3b7
commit
22f33d4004
5278 changed files with 84726 additions and 14379 deletions
64
Task/Hash-join/C++/hash-join.cpp
Normal file
64
Task/Hash-join/C++/hash-join.cpp
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
|
||||
using tab_t = std::vector<std::vector<std::string>>;
|
||||
tab_t tab1 {
|
||||
// Age Name
|
||||
{"27", "Jonah"}
|
||||
, {"18", "Alan"}
|
||||
, {"28", "Glory"}
|
||||
, {"18", "Popeye"}
|
||||
, {"28", "Alan"}
|
||||
};
|
||||
|
||||
tab_t tab2 {
|
||||
// Character Nemesis
|
||||
{"Jonah", "Whales"}
|
||||
, {"Jonah", "Spiders"}
|
||||
, {"Alan", "Ghosts"}
|
||||
, {"Alan", "Zombies"}
|
||||
, {"Glory", "Buffy"}
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& o, const tab_t& t) {
|
||||
for(size_t i = 0; i < t.size(); ++i) {
|
||||
o << i << ":";
|
||||
for(const auto& e : t[i])
|
||||
o << '\t' << e;
|
||||
o << std::endl;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
tab_t Join(const tab_t& a, size_t columna, const tab_t& b, size_t columnb) {
|
||||
std::unordered_multimap<std::string, size_t> hashmap;
|
||||
// hash
|
||||
for(size_t i = 0; i < a.size(); ++i) {
|
||||
hashmap.insert(std::make_pair(a[i][columna], i));
|
||||
}
|
||||
// map
|
||||
tab_t result;
|
||||
for(size_t i = 0; i < b.size(); ++i) {
|
||||
auto range = hashmap.equal_range(b[i][columnb]);
|
||||
for(auto it = range.first; it != range.second; ++it) {
|
||||
tab_t::value_type row;
|
||||
row.insert(row.end() , a[it->second].begin() , a[it->second].end());
|
||||
row.insert(row.end() , b[i].begin() , b[i].end());
|
||||
result.push_back(std::move(row));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, char const *argv[])
|
||||
{
|
||||
using namespace std;
|
||||
int ret = 0;
|
||||
cout << "Table A: " << endl << tab1 << endl;
|
||||
cout << "Table B: " << endl << tab2 << endl;
|
||||
auto tab3 = Join(tab1, 1, tab2, 0);
|
||||
cout << "Joined tables: " << endl << tab3 << endl;
|
||||
return ret;
|
||||
}
|
||||
27
Task/Hash-join/Perl-6/hash-join.pl6
Normal file
27
Task/Hash-join/Perl-6/hash-join.pl6
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
sub hash-join(@a, &a, @b, &b) {
|
||||
my %hash := @b.classify(&b);
|
||||
|
||||
@a.map: -> $a {
|
||||
|(%hash{a $a} // next).map: -> $b { [$a, $b] }
|
||||
}
|
||||
}
|
||||
|
||||
# Testing:
|
||||
|
||||
my @A =
|
||||
[27, "Jonah"],
|
||||
[18, "Alan"],
|
||||
[28, "Glory"],
|
||||
[18, "Popeye"],
|
||||
[28, "Alan"],
|
||||
;
|
||||
|
||||
my @B =
|
||||
["Jonah", "Whales"],
|
||||
["Jonah", "Spiders"],
|
||||
["Alan", "Ghosts"],
|
||||
["Alan", "Zombies"],
|
||||
["Glory", "Buffy"],
|
||||
;
|
||||
|
||||
.say for hash-join @A, *[1], @B, *[0];
|
||||
|
|
@ -1,26 +1,43 @@
|
|||
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 mut hash_map = HashMap::new();
|
||||
|
||||
// hash phase
|
||||
for &(key, val_a) in second {
|
||||
// collect all values by their keys, appending new ones to each existing entry
|
||||
hash_map.entry(key).or_insert_with(Vec::new).push(val_a);
|
||||
}
|
||||
|
||||
let mut result = Vec::new();
|
||||
// join phase
|
||||
for &(key, val_b) in first {
|
||||
if let Some(vals) = hash_map.get(&key) {
|
||||
let tuples = vals.iter().map(|&val_a| (val_b, key, val_a));
|
||||
result.extend(tuples);
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let table_a = vec![
|
||||
(27, "Jonah"), (18, "Alan"), (28, "Glory"),
|
||||
(18, "Popeye"), (28, "Alan")
|
||||
];
|
||||
let table_b = vec![
|
||||
let table1 = [("Jonah", 27), ("Alan", 18), ("Glory", 28), ("Popeye", 18), ("Alan", 28)];
|
||||
let table2 = [
|
||||
("Jonah", "Whales"), ("Jonah", "Spiders"), ("Alan", "Ghosts"),
|
||||
("Alan", "Zombies"), ("Glory", "Buffy")
|
||||
];
|
||||
// hash phase
|
||||
let mut h = HashMap::new();
|
||||
for (i, a) in table_a.iter().enumerate() {
|
||||
h.entry(a.1).or_insert_with(Vec::new).push(i);
|
||||
}
|
||||
// join phase
|
||||
for b in table_b {
|
||||
if let Some(vals) = h.get(b.0) {
|
||||
for &val in vals {
|
||||
let a = table_a.get(val).unwrap();
|
||||
println!("{:?} {:?}", a, b);
|
||||
}
|
||||
}
|
||||
let result = hash_join(&table1, &table2);
|
||||
println!("Age | Character Name | Nemesis");
|
||||
println!("----|----------------|--------");
|
||||
for (age, name, nemesis) in result {
|
||||
println!("{:<3} | {:^14} | {}", age, name, nemesis);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue