boulder_ruby
boulder_ruby

Reputation: 39695

what's a clean way of finding which common elements exist in a set of n arrays?

I'm going through a table in my database that has a lot of optional columns. I'm wanting to find the columns which have data in every record in my database.

A simplified example of what I'm trying to do is as follows:

[1,2,3,4,5] & [1,2,3,4] & [1,2,3] & [1,2]
#=> [1,2]

However, what I'm trying to do is run this type of operation for thousands of records. What's a clean way to accomplish this? I have the feeling that ruby might have some bespoke methods for this sort of thing.

Here's what I was about to do before I decided to write this question:

sets_of_columns_with_data = TableName.all.map(&:attributes).map do |attrs| 
    attrs.select {|k,v| v}
end.map(&:keys)

So at this point, if you were following the above code, columns_with_data is now the equivalent of this:

sets_of_columns_with_data = [
  [1,2,3,4,5],
  [1,2,3,4],
  [1,2,3]
  [1,2]
 ]

A messy way to do this I guess would look something like this:

always_used = sets_of_columns_with_data.first
sets_of_columns_with_data.each do |columns_with_data|
  always_used = always_used & columns_with_data
end

What's the clean, ruby-way to do something like this?

Thanks

NOTE:

I'm keeping the business logic for sake of clarity, but generally this is not the best solution when you have SQL available to you.

Upvotes: 1

Views: 39

Answers (1)

Stefan
Stefan

Reputation: 114158

I'm not sure if this solves the actual problem, but to apply a binary operation, you can use reduce:

sets_of_columns_with_data = [
  [1, 2, 3, 4, 5],
  [1, 2, 3, 4],
  [1, 2, 3],
  [1, 2]
]

sets_of_columns_with_data.reduce(:&) #=> [1, 2]

Upvotes: 3

Related Questions