Ruby: как найти сходство в двух массивах - PullRequest
0 голосов
/ 08 мая 2019

Я пытаюсь найти общие элементы в двух массивах.

pairs = Array.new
a = exchange_one.get_symbols
b = exchange_two.get_symbols
c = a+b
c.uniq{|pair| pairs << pair}

Я объединяю два массива, используя +

Затем я звоню uniq для удаления дубликата, но передача его в блок, чтобы найденные дубликаты могли быть добавлены в массив до их удаления.

По некоторым причинам пары массивов - это всего лишь c массив.

Как правильно найти сходство массивов.

Ответы [ 3 ]

6 голосов
/ 08 мая 2019

Если ваша цель - просто определить, какие элементы одинаковы между двумя массивами, вы можете использовать оператор пересечения Array#&.

a = exchange_one.get_symbols
b = exchange_two.get_symbols

intersection = a & b
2 голосов
/ 08 мая 2019

Сначала поймите, что вы делаете и чего хотите.

Например,

a = 15.times.map { rand 6 }
  #=> [1, 0, 5, 3, 1, 3, 4, 1, 3, 2, 1, 2, 4, 2, 3]
b = 15.times.map { rand 6 }
  #=> [3, 3, 3, 1, 3, 1, 3, 1, 5, 1, 4, 2, 0, 0, 4]

Теперь, что ты делаешь

c = a + b 
  #=> [1, 0, 5, 3, 1, 3, 4, 1, 3, 2, 1, 2, 4, 2, 3, 3, 3, 3, 1, 3, 1, 3, 1, 5, 1, 4, 2, 0, 0, 4]

c - объединять только массивы независимо от содержимого, поэтому получать все значения.

Теперь

pairs = Array.new
c.uniq{|pair| pairs << pair}

Здесь uniq просто действует как итератор, означает, что если вы проверяете «pair», то он повторяет все значения «c» и вставляет эти значения в массив «pair».

отметьте это

c.uniq{|pair| puts pair}

Вот почему вы получаете все значения в массиве 'pair'.

Лучший способ найти сходство в массивах - это (a&b), но вы можете внести изменения в свой код следующим образом для достижения этого.

 pairs = (arr1+arr2).uniq

OR

 pairs = arr1 & arr2 #best and efficient way.

1 голос
/ 08 мая 2019

Предположим:

arr1 = 15.times.map { rand 6 }
  #=> [1, 0, 4, 0, 2, 3, 1, 0, 2, 4, 4, 1, 3, 1, 1] 
arr2 = 15.times.map { rand 6 }
  #=> [5, 5, 4, 1, 5, 1, 5, 0, 4, 0, 2, 0, 4, 5, 0] 

arr1 содержит 5 1 с, а arr2 содержит 2 1 с. Если по «общим элементам» вы хотите сообщить, что оба массива содержат [5, 2].min #=> 2 1 s, и аналогичные значения для других элементов, присутствующих в любом массиве, вы можете сделать следующее:

h1 = count(arr1)
  #=> {1=>5, 0=>3, 4=>3, 2=>2, 3=>2} 
h2 = count(arr2)
  #=> {5=>5, 4=>3, 1=>2, 0=>4, 2=>1} 
(h1.keys | h2.keys).each_with_object({}) { |k,h| h[k] = [h1[k], h2[k]].min }
  #=> {1=>2, 0=>3, 4=>3, 2=>1, 3=>0, 5=>0}

def count(arr)
  arr.each_with_object(Hash.new(0)) { |n,h| h[n] += 1 }
end
...