Может кто-нибудь объяснить, пожалуйста, как использовать each_with_index, уменьшить, выбрать цепочку в коде вместе с ИЛИ (||)? - PullRequest
0 голосов
/ 10 апреля 2019

Может кто-нибудь объяснить мне этот код? Что означает синтаксис || и как он работает?

array = [1, 2, 3, 4, 5, 3, 6, 7, 2, 8, 1, 9]

array.each_with_index.reduce({}) { |hash, (item, index)|
  hash[item] = (hash[item] || []) << index
  hash
}.select{ |key, value| value.size > 1 }

Ответы [ 3 ]

1 голос
/ 10 апреля 2019

Я бы переписал это так

array.each_with_index.reduce(Hash.new { Array.new }) do |hash, (item, index)|
  hash.merge(item => hash[item] << index)
end.select { |_, indexes| indexes.size > 1 }
  • Мы используем each_with_index, потому что мы хотим получить доступ к индексу во время зацикливания массива. Вы можете увидеть его позже рядом с элементом в качестве параметра в блоке reduce.
  • reduce позволяет нам «преобразовывать» коллекцию во что-то еще. В нашем случае мы хотим построить хеш из массива.
  • В блоке reduce мы добавляем текущий индекс к паре ключ-значение для текущего элемента. Я использовал merge, чтобы сделать это только в одном выражении (обновить хеш и использовать его в качестве выражения для возврата).
  • В конце мы сохраняем только пары ключ-значение, значения которых (и это массивы) имеют более одного элемента. Обратите внимание, что здесь мы не заботимся о ключах, поэтому я назвал параметр ключа _.
0 голосов
/ 10 апреля 2019

hash[item] - это сначала nil.nil || [] => [], поэтому hash[item] становится массивом.<< вставить элемент в массив.

надеюсь, что это поможет вам понять, как хэш хранит значение

require "pp"
hash = {}
pp hash[1] # => nil 
pp hash[1] || [] # => []
pp (hash[1] || []) << 1 # => [1]
pp hash[1] # => nil
hash[1] = (hash[1] || []) << 1
pp hash[1] # => [1]
0 голосов
/ 10 апреля 2019
array = [1, 2, 3, 4, 5, 3, 6, 7, 2, 8, 1, 9]

array.each_with_index.reduce({}) do |hash, (item, index)|
  hash[item] = (hash[item] || []) << index
  hash
end.select do |key, value|
  value.size > 1
end

Прежде всего, более понятный способ записи. Перечислим одну строку, заключенную в {}, и многострочную do; end.

array.each_with_index.reduce({}) do |hash, (item, index)|
  # hash[item] gets either itself and if itself is nil it gets an empty 
  # array assigned and additionally the index gets added to this array 
  hash[item] = (hash[item] || []) << index
  # return the hash for the reduce enumerator
  hash
end

В этой части вы перебираете массив и передаетеначальный пустой хеш с .reduce({}).Затем хэш преобразуется и возвращается в L3 в «цикле» и передается в следующую итерацию reduce.Тогда ваш результат - это компоновка hash, которая затем сразу же перечисляется с select, где возвращаются только пары ключ-значение, размер которых больше 1.

Лучше всего будет считывание на Перечислители # уменьшают и то, как объекты передаются в «цикл».

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