2013-06-26 2 views
-2

У меня есть два массива:Объединение 2 Массивы на основе одного столбца

a = [[1234,1],[2134,0],[4321,0],[2221,3]] 
b = [[2134,1],[4321,3]] 

Я хочу, чтобы объединить их на основе первых элементов a для следующего результата:

c = [[1234,1],[2134,1],[4321,3],[2221,3]] 

Я хочу, чтобы заменить 0 в a по значению в b, если совпадение первого элемента. Первый элемент уникален в а и b.

Как это сделать?

Спасибо заранее,

+2

неясно, как объединить их. они должны быть отсортированы как минимум. – Tala

+1

Я не следую условию слияния. Вы выбираете один с самым большим 2-м элементом? – lurker

+2

Возможно, это сумма вторых значений. Но никто не знает, потому что один из них всегда 0 в своем примере. – tessi

ответ

2

Hash#merge функция позволяет задать блок, чтобы определить, что делать с ценностями.

a = [[1234,1],[2134,0],[4321,0],[2221,3]] 
b = [[2134,1],[4321,3]] 
c = Hash[a].merge(Hash[b]) { |key, old, new| old+new }.to_a 
# => [[1234, 1], [2134, 1], [4321, 3], [2221, 3]] 

См. Hash#merge documentation.

В этом случае я сделал слияние, построив сумму значений. Вы можете выбрать наибольшее значение или какую-либо другую стратегию, которая вам подходит.

Отказ от ответственности: Этот подход не работает, если a (или b) содержит массивы, имеющие один и тот же первое значение. Пример [[1, 1], [1, 4], [2, 8]]. Это не указано в вашем вопросе, если это может произойти.

+0

на цель! Nice @tessi –

1

Учитывая

a = [[1234,1],[2134,0],[4321,0],[2221,3]] 

и

b = [[2134,1],[4321,3]] 

Вы могли бы превратить эти массивы в хэшей, выполнить слияние, а затем преобразовать результат в массив снова.

Hash[a].merge(Hash[b]).to_a 
#=> [[1234, 1], [2134, 1], [4321, 3], [2221, 3]] 
1

Вот одна возможность:

a = [[1234,1],[2134,0],[4321,0],[2221,3]] 
b = [[2134,1],[4321,3]] 

a.zip(b).flatten(1).uniq(&:first) 
# => [[1234, 1], [2134, 1], [4321, 3], [2221, 3]] 
+0

Зачем беспокоиться о почтовом индексе? Просто измените массивы: '(b + a) .uniq (&: first)' –

+0

Правда, но неясно, что именно нужно сделать. Я решил их чередовать. –

0
[*a, *b].group_by(&:first).map{|k, v| [k, v.map(&:last).inject(:+)]} 
+0

Мне нравится этот подход, я использовал это сегодня. Благодарим за обмен @sawa –

0

Просто поменять местами массивы и назвать уникальным:

(b + a).uniq(&:first) 

Это работает, потому что Array#+ не является мутирует версия Array#concat. Он создаст новый упорядоченный массив. Какой бы ни был массив, он будет иметь приоритет в выходе. Когда вызывается uniq, он будет перечислять по массиву по порядку, позволяя просто получить первый экземпляр первого столбца.

Вы можете сделать это для n массивов:

[b,d,c,a].reduce(&:+).uniq(&:first)