Is this the best way to grab common elements from a Hash of arrays?
Behold the power of inject
! ;)
[[1,2,3],[1,3,5],[1,5,6]].inject(&:&)
=> [1]
As Jordan mentioned, if your version of Ruby lacks support for &-notation, just use
inject{|acc,elem| acc & elem}
How do I breakdown common elements in hash of arrays in perl?
This can be done as two simple hash conversions:
Build a hash that lists all of the lots each item is in
Convert that to a hash that lists all items for each lot combination
Then just dump the last hash in a convenient form
This is the code.
use strict;
use warnings 'all';
use feature 'say';
my %test = (
Lot1 => [ "A", "B", "C" ],
Lot2 => [ "A", "B", "C" ],
Lot3 => ["C"],
Lot4 => [ "E", "F" ],
);
my %items;
for my $lot ( keys %test ) {
for my $item ( @{ $test{$lot} } ) {
push @{ $items{$item} }, $lot;
}
}
my %lots;
for my $item ( keys %items ) {
my $lots = join '!', sort @{ $items{$item} };
push @{ $lots{$lots} }, $item;
}
for my $lots ( sort keys %lots ) {
my @lots = split /!/, $lots;
my $items = join '', @{ $lots{$lots} };
$lots = join ', ', @lots;
$lots =~ s/.*\K,/ and/;
printf "%s %s %s\n", $lots, @lots > 1 ? 'have' : 'has', $items;
}
output
Lot1 and Lot2 have AB
Lot1, Lot2 and Lot3 have C
Lot4 has EF
It generates an %items
hash that looks like this
{
A => ["Lot2", "Lot1"],
B => ["Lot2", "Lot1"],
C => ["Lot2", "Lot3", "Lot1"],
E => ["Lot4"],
F => ["Lot4"],
}
and from that a %lots
hash that looks like this
{
"Lot1!Lot2" => ["A", "B"],
"Lot1!Lot2!Lot3" => ["C"],
"Lot4" => ["E", "F"],
}
How to use HashSet to find common elements in two Comparable arrays?
EDIT I forgot to mention that I imported the Apache Commons Array Utils. Very useful.
I figured it out. Thanks for all your help. I have a main method that calls an instance of the class 3 times, and 3 test methods, but those are irrelevant. Here is what was giving me trouble, and now it works. :-)
public int getComparisons() {
return comparisons;
} //method to return number of comparisons
public static Comparable[] findCommonElements(Comparable[][] collections) {
/*
I LEARNED THAT WE HAD TO USE MORE THAN TWO ARRAYS, SO IT WAS BACK
TO THE DRAWING BOARD FOR ME. I FIGURED IT OUT, THOUGH.
*/
Comparable[] arr1 = collections[0]; //set initial values to 1 Dimensional arrays so the test methods can read their respective values
Comparable[] arr2 = collections[1];
Comparable[] arr3 = collections[2];
/*
THE FOLLOWING BLOCK OF CODE TAKES ALL THE PERMUTATIONS OF THE 3 ARRAYS (i.e. 1,2,3; 1,3,2; 2,1,3, etc),
DETERMINES WHICH ARRAY IS THE SHORTEST, AND ADDS THE LONGER TWO ARRAYS TO A QUERY ARRAY.
*/
if(arr1.length < arr2.length && arr1.length < arr3.length || arr2.length <= arr3.length) { //shortest array will become hash array. the other two will become a combined query array.
hashArray = arr1; //these will be utilized below to put into Sets
queryArray = ArrayUtils.addAll(arr2, arr3);
}
else if(arr2.length < arr1.length && arr2.length < arr3.length || arr1.length <= arr3.length) {
hashArray = arr2;
queryArray = ArrayUtils.addAll(arr1, arr3);
}
else if(arr3.length < arr1.length && arr3.length < arr2.length || arr1.length <= arr2.length) {
hashArray = arr3;
queryArray = ArrayUtils.addAll(arr1, arr2);
}
HashSet<Comparable> intersectionSet = new HashSet<>(); //initialize Sets
HashSet<Comparable> arrayToHash = new HashSet<>();
for(Comparable element : hashArray) { //add shorter array to hashedArray Set
arrayToHash.add(element);
}
//NOTE FROM THE JAVADOC ON THE IMPLEMENTATION OF .contains() USING HASHSET COMPARISONS
/**
* <p>This class offers constant time performance for the basic operations
* (<tt>add</tt>, <tt>remove</tt>, <tt>contains</tt> and <tt>size</tt>),
* assuming the hash function disperses the elements properly among the
* buckets.
*/
for(Comparable element : queryArray) {
if(element != null) {
comparisons++; // increment comparisons with each search
}
if(arrayToHash.contains(element)) { //search for matches and add to intersectionSet (.contains uses the equals method to determine if an object is within array)
intersectionSet.add(element);
}
}
return intersectionSet.toArray(new Comparable[0]); //return Set as Array defined in method signature
}
How do I find common elements from n arrays
I advocate for hashes in such cases: you'll have time proportional to common size of both arrays.
Since most major languages offer hashtable in their standard libraries, I hardly need to show your how to implement such solution.
Compare arrays in Ruby and print common elements
Hmmm... Not that I'm a judge, by why not use the Array#&
method?
Set Intersection — Returns a new array containing elements common to the two arrays, excluding any duplicates. The order is preserved from the original array.
arr1 = [1, 2, 3, 4, 5]
arr2 = [1, 3, 5, 7, 9]
arr1 & arr2 # => [1, 3, 5]
How do I find common elements from n arrays
I advocate for hashes in such cases: you'll have time proportional to common size of both arrays.
Since most major languages offer hashtable in their standard libraries, I hardly need to show your how to implement such solution.
Related Topics
/Usr/Bin/Env Ruby_Noexec_Wrapper Fails with No File or Directory
Create a Human-Readable List with "And" Inserted Before the Last Element from a Ruby List
Could Not Find Rake with Bundle Exec
Custom Filtering of Parameters in Rails 3 Using Config.Filter_Parameters
Twitter 3-Legged Authorization in Ruby
Error Installing Ruby 2.6.7 on MAC Os - How to Resolve
Rvm Error While Running Make Install. Error Comes While Installing Power_Assert Gem
Bundle Install/Error in Installing Libv8 (3.3.10.4) on Rails (Running on Lion)
How to Handle Utf-8 Email Headers (Like Subject:) Using Ruby
Rails 5.0.0 When Installing "Nio4R":Failed to Build Gem Native Extension
Custom_Require.Rb:36:In 'Require': No Such File to Load -- Myapp(Loaderror)
Database Cleaner Not Working in Minitest Rails
Ruby Tcpsocket: Find Out How Much Data Is Available
What Are the Differences Between Lazy, Greedy and Possessive Quantifiers
Rails: How to Print a Decimal as a Percent