Как я могу улучшить этот Array.select в Ruby? - PullRequest
0 голосов
/ 24 ноября 2010

Я только что написал эту ... ужасную строку кода на Ruby, и мне интересно, нет ли лучшего способа сделать это.

У меня есть массив хэшей, из которых я хочу получить один. «Условия» того, что я хочу выбрать, находятся в двух отдельных массивах - один с ключами и один со значениями. Если хеш в массиве имеет правильные значения key == value для каждой пары в keys и values, я хочу вернуть этот хэш.

Какие-нибудь указатели, чтобы сделать код более читабельным?

arr = [
  {:foo => 'foo', :bar => 'bar', :baz => 'baz'},
  {:foo => 'bar', :bar => 'bar', :baz => 'bar'},
  {:foo => 'foo', :bar => 'foo', :baz => 'foo'},
]

keys = [:foo, :bar]
values  = ['foo', 'bar']

arr.select{|c| keys.map{|k| i = keys.index(k); c[keys[i]] == values[i]}.delete(false) != false}.first
# => {:foo => 'foo', :bar => 'bar', :baz => 'baz'}

Ответы [ 2 ]

2 голосов
/ 24 ноября 2010
arr = [
  {foo:'foo', bar:'bar', baz:'baz'},
  {foo:'bar', bar:'bar', baz:'bar'},
  {foo:'foo', bar:'foo', baz:'foo'},
]

keys = [:foo, :bar]
values = ['foo', 'bar']

p arr.find { |c|
    keys.zip(values).all? { |k,v|
        c[k] == v
    }
}
  1. Вы можете использовать синтаксис {foo:'bar'} для объявления хэшей, если в качестве ключа используется символ.
  2. Используйте Enumerable#find, чтобы найти первый случай.
2 голосов
/ 24 ноября 2010

Нужно ли указывать то, что вы ищете, как массив ключей и массив значений? Если вы это сделаете, то конвертируйте их в Hash следующим образом:

hsh = Hash[*keys.zip(values).flatten]  #=> {:foo=>"foo", :bar=>"bar"}

А затем выберите вот так:

arr.select { |c| c == c.merge(hsh) }   #=> [{:foo=>"foo", :bar=>"bar", :baz=>"baz"}]

Если вы в первую очередь можете указать, что вы ищете как хэш, вам не нужна первая строка.

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