0

Assuming the following data tuple containing a person's name, age and the books he has read:

list =     [
  ["Peter", 21, ["Book 1", "Book 2", "Book 3", "Book 4"],
  ["Amy", 19, ["Book 3", "Book 4"],
  ["Sanders", 32, ["Book 1", "Book 2",],
  ["Charlie", 21, ["Book 4", "Book 5", "Book 6"],
  ["Amanda", 21, ["Book 2", "Book 5"]
]

What is the optimal way to extract names grouped by the books read, into the following format (basically a an array of arrays containing the book name and an array of names of people who read it)

results = [
   ["Book 1", ["Sanders", "Peter"]],
   ["Book 2", ["Sanders" "Amanda", "Peter"]],
   ["Book 3", ["Peter", "Amy"]],
   ["Book 4", ["Charlie", "Peter", "Amy"]],
   ["Book 5", ["Amanda","Charlie"]],
   ["Book 6", ["Charlie"]]
]

I've tried the following iterating method which extracts the lists of names and puts them into a hash, with the book title as the keys.

book_hash = Hash.new([])
list.each { |name,age,books| 
books { |x|  book_hash[x] = book_hash[x] + [name] }
}
results = book_hash.to_a.sort

However, the above method seems rather inefficient when handling large datasets containing millions of names. I've attempted to use the Array.group_by, but so far I'm unable to make it work with nested arrays.

Does anyone have any idea about the above?

3
  • Why are you expecting an array where your solution gives a hash? A hash makes more sense in this case. Commented Mar 3, 2015 at 13:43
  • 1
    Don't be lazy. You should provide at least enough sample data for your list that would correspond to your sample result. Commented Mar 3, 2015 at 13:44
  • @sawa My apologies, I've just added some sample data and results. Commented Mar 4, 2015 at 5:39

1 Answer 1

2

Hash output. More suitable.

list.each_with_object({}) do |(name, age, books), hash|
  books.each do |book|
    (hash[book] ||= []) << name    
  end
end

If you must make it an array, then append a .to_a to the output of the above.

Sign up to request clarification or add additional context in comments.

1 Comment

This did the trick, but since I'm running 1.8.7 I opted for for .each instead of .each_with_object. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.