2014-01-06 2 views
0

Допустит, у меня есть 2 массива хэш следующим образом,рубин - Сравнить/объединить 2 массива хэш на основе 1 ключ

local_todos = [{name: "abc", title: "abcdwer", api_id: "1234567", updated_at: "2013-22-12"}, 
{name: "abcd", title: "abcdwe", api_id: "098098", updated_at: "2013-22-11"}, 
{name: "abcde", title: "abcdqw", api_id: "345345", updated_at: "2013-22-18"}, 
{name: "abcdef", title: "abcder", api_id: "234456", updated_at: "2013-22-15"}] 

google_tasks = [{name: "abc", title: "xxxxx", id: "1234567", updated: "2013-22-19"}, 
{name: "abcd", title: "zzzzz", id: "098098", updated: "2013-22-15"}, 
{name: "abcde", title: "abcdqw", id: "345345", updated: "2013-22-18"}, 
{name: "abcdef", title: "abcder", id: "234456", updated: "2013-22-15"}] 

Теперь я хочу, объединить/сравнение/фильтровать эти 2 хэш чисто на основе api_id (local_todos) и id (google_tasks), , так что только идентификатор id/api_id (оба одинакового значения), который имеет разницу в значении updated_at (local_todos) и обновленном (google_tasks), печатается как выход.

Желаемый результат будет, как это,

["1234567", "098098"] 

Потому что, если вы проверить эти 2 иды имеет различные обновленные значения/updated_at.

Любая помощь?

+2

Было бы хорошо, если бы вы предоставили нам желаемый результат. Только описания недостаточно. –

+0

Помогает ли это сейчас? Добавлен желаемый результат и немного изменил описание. – beck03076

ответ

2

Просто простой выбор:

local_todos.map do | v1 | 
    google_tasks.any? {|v2| v1[ :api_id ] == v2[ :id ] && v1[ :updated_at ] != v2[ :updated ] } && v1[ :api_id ] || nil 
end.compact 
# => ["1234567", "098098"] 

Для сравнения кода вы можете использовать следующий код:

funcs = 
[ proc { local_todos.map {|v1| google_tasks.any? {|v2| v1[ :api_id ] == v2[ :id ] && v1[ :updated_at ] != v2[ :updated ] } && v1[ :api_id ] || nil }.compact }, 
    proc { 
    local_todos.inject([]) do |result,l_td| 
    if found = google_tasks.detect {|g_td| g_td[:id] == l_td[:api_id] and g_td[:updated] != l_td[:updated_at]} 
     result << found[:id] 
    end 
    result 
    end 
}, 
] 

def ctime func 
    time = 0 
    1000.times { time += Benchmark.measure { 1000.times { func.call } }.to_a[5].to_f } 
    rtime = time /= 1000000 
end 

funcs.each {| func | p ctime(func) } 

# 3.9753190517425536e-05 
# 4.056975722312927e-05 

В моей скамейке результаты первого кода незначителен Быстрее.

+0

Как узнать, какой из них работает быстрее..я или priteshs? – beck03076

+0

@ beck03076 обновлено –

2
local_todos.inject([]) do |result,l_td| 
    if found = google_tasks.detect {|g_td| g_td[:id] == l_td[:api_id] and g_td[:updated] != l_td[:updated_at]} 
     result << found[:id] 
    end 
    result 
end 
+0

Большое вам спасибо! – beck03076

+0

Извините, человек быстрее, а также читается – beck03076

0
local_todos.collect do |l_todo| 
    google_tasks.collect do |g_task| 
    l_todo[:api_id] if (l_todo[:api_id] == g_task[:id] && l_todo[:updated_at] != g_task[:updated]) 
    end.compact 
end.flatten 
Смежные вопросы