Как вытащить идентификаторы из массива хэшей на ruby? - PullRequest
0 голосов
/ 06 ноября 2019

Учитывая:

data = [
  {"id"=>nil, "votable_id"=>1150, "user_ids"=>"1120,1119,1118,1117,1116,1115,1114,1113,1112,1111,1110,1109,1108,1107"},
  {"id"=>nil, "votable_id"=>1151, "user_ids"=>"1120,1119,1118,1117,1116,1115,1114,1113,1112,1111,1110,1109,1108,1107"}
]

Я хочу вернуть массив всех уникальных представлений целых чисел в строках g["user_ids"], взятых по всем хэшам g, которые являются элементами data;а именно

["1120", "1119", "1118", "1117", "1116", "1115", "1114",
 "1113", "1112", "1111", "1110", "1109", "1108", "1107"]

Ответы [ 3 ]

2 голосов
/ 06 ноября 2019

Если вы используете Rails, попробуйте следующее:

data.pluck('user_ids').join(',').split(',').uniq

Если вы не используете Rails:

data.map{ |d| d.dig('user_ids') }.join(',').split(',').uniq

Результат:

#=> [
#     "1120", "1119", "1118", "1117", "1116", "1115", "1114",
#     "1113", "1112", "1111", "1110", "1109", "1108", "1107"
#   ]
2 голосов
/ 06 ноября 2019

Чтобы получить уникальные идентификаторы:

unique_ids = data.flat_map { |d| d['user_ids'].split(',') }.uniq
  1. Enumerable#flat_map проходит по массиву и объединяет результаты, представленные в блоке кода.
  2. String#split делит строку по разделителю на массив.
  3. Array#uniq удаляет дубликаты.
0 голосов
/ 06 ноября 2019
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 .

Обратите внимание, что возвращаемый массив содержит те же элементы, что и массив, возвращенный ранее, но в другом порядке. Я предполагаю, что это не импорт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...