You have a 2-dimensional array of strings:
[
["AAA", "BBB", "CCC", "DDD"],
["BBB", "CCC", "DDD"],
["AAA", "CCC", "DDD"],
["AAA", "CCC", "DDD", "EEE"]
]
You need to compare each subarray with other subarrays to get result as a 2-dimensional array which will show whether each string present in the current subarray and in other subarrays or not (if not - it should be nil) like this (RESULT):
[
["AAA", nil, "AAA", "AAA"],
["BBB", "BBB", nil, nil],
["CCC", "CCC", "CCC", "CCC"],
["DDD", "DDD", "DDD", "DDD"],
[nil, nil, nil, "EEE"]
]
How to write a function that takes an initial array and returns array like in the RESULT example?
CodePudding user response:
if list has the next values:
list = [
["AAA", "BBB", "CCC", "DDD"],
["BBB", "CCC", "DDD"],
["AAA", "CCC", "DDD"],
["AAA", "CCC", "DDD", "EEE"]
]
then
def method_name(list)
handled_list = list.flatten.uniq
handled_list.each_with_object([]) do |item, res|
res << list.map{ |sub_array| sub_array.find{ |s| s == item } }
end
end
CodePudding user response:
arr = [
["AAA", "BBB", "CCC", "DDD"],
["BBB", "CCC", "DDD"],
["AAA", "CCC", "DDD"],
["AAA", "CCC", "DDD", "EEE"]
]
all = arr.reduce(:|)
#=> ["AAA", "BBB", "CCC", "DDD", "EEE"]
arr.map { |row| all.map { |s| row.include?(s) ? s : nil } }.transpose
#=> [["AAA", nil, "AAA", "AAA"],
# ["BBB", "BBB", nil, nil],
# ["CCC", "CCC", "CCC", "CCC"],
# ["DDD", "DDD", "DDD", "DDD"],
# [ nil, nil, nil, "EEE"]]
See Array#| (array union) for calculating all
.
transpose
's receiver equals
arr.map { |row| all.map { |s| row.include?(s) ? s : nil } }
#=> [["AAA", "BBB", "CCC", "DDD", nil],
# [ nil, "BBB", "CCC", "DDD", nil],
# ["AAA", nil, "CCC", "DDD", nil],
# ["AAA", nil, "CCC", "DDD", "EEE"]]