data.reduce('') { |s,h| s + h['user_ids'] + ',' }.scan(/\d+/).uniq
#=> ["1120", "1119", "1118", "1117", "1116", "1115", "1114", "1113",
# "1112", "1111", "1110", "1109", "1108", "1107"]
Шаги следующие:
str = data.reduce('') { |s,h| s + h['user_ids'] + ',' }
=> "1120,1119,...1107,1120,1119,...1107,"
arr = str.scan(/\d+/)
#=> ["1120", "1119", "1118", "1117", "1116", "1115", "1114", "1113",
# "1112", "1111", "1110", "1109", "1108", "1107", "1120", "1119",
# "1118", "1117", "1116", "1115", "1114", "1113", "1112", "1111",
# "1110", "1109", "1108", "1107"]
arr.uniq
#=> ["1120", "1119", "1118", "1117", "1116", "1115", "1114", "1113",
# "1112", "1111", "1110", "1109", "1108", "1107"]
Проблема с этим подходом заключается в том, что промежуточный массив arr
может быть довольно большим, если data
содержит много элементов (хэшей) и длякаждый элемент h
, h['user_ids'].split(',')
содержит много элементов. Одним из способов решения этой проблемы является создание набора, который, конечно, содержит уникальные элементы, а затем преобразование этого набора в массив в конце.
require 'set'
data.each_with_object(Set.new) { |h,set|
h["user_ids"].split(',').each { |s| set << s } }.to_a
#=> ["1120", "1119", "1118", "1117", "1116", "1115", "1114",
# "1113", "1112", "1111", "1110", "1109", "1108", "1107"]
См. Set :: new , Set # << </a> и Set # to_a .
Обратите внимание, что возвращаемый массив содержит те же элементы, что и массив, возвращенный ранее, но в другом порядке. Я предполагаю, что это не импорт.