Пересечение массива хэшей с массивом идентификаторов

#ruby-on-rails #ruby

#ruby-on-rails #ruby

Вопрос:

У меня есть массив хэшей, это не модель активной записи. Этот массив состоит из объектов типа Person со свойствами id , name age . У меня есть второй массив строк, ["john", "james", "bill"] .

Я пытаюсь удалить все объекты из массива хэшей, за исключением тех, у которых есть имена во втором массиве, по сути, выполняя пересечение, но у меня возникает довольно много проблем. Есть предложения? Я не уверен, что мой синтаксис просто отключен или я думаю об этом неправильно. Очевидно, что я могу просто выполнить итерацию, но это, вероятно, не лучший способ справиться с ситуацией.

Ответ №1:

http://www.ruby-doc.org/core-1.9.2/Array.html#method-i-select

 arr1 = [{:id => 1, :name => "John"}, {:id => 2, :name => "Doe"}];
arr2 = ["Doe"];

intersect = arr1.select {|o| arr2.include? o[:name]} # you can also use select!
p intersect # outputs [{:name=>"Doe", :id=>2}]
  

Комментарии:

1. Я бы создал набор из arr2 , который устраняет затраты на поиск O (n).

Ответ №2:

Опоздание на вечеринку, но если arr1 : name является массивом, это прекрасно работает:

 arr1 = [{:id => 1, :name => ["John", "Doe"]}, {:id => 2, :name => ["Doe"]}];
arr2 = ["Doe"]

> intersect = arr1.reject{|o| (arr2 amp; o[:name]).empty?}
=> [{:id=>1, :name=>["John", "Doe"]}, {:id=>2, :name=>["Doe"]}] #output

> arr2 = ["John"]
> intersect = arr1.reject{|o| (arr2 amp; o[:name]).empty?}
=> [{:id=>1, :name=>["John", "Doe"]}] #output
  

или используйте select:

 intersect = arr1.select{|o| !(arr2 amp; o[:name]).empty?}
  

Чтобы удалить все объекты в массиве хэшей, за исключением тех, у которых есть имена во втором массиве, вы можете сделать:

 arr1.reject!{|o| (arr2 amp; o[:name]).empty?}