Объединить три массива хешей по-разному - PullRequest
1 голос
/ 03 мая 2020

Я новичок в Ruby и пытаюсь создать приложение для собраний. У меня есть три массива, содержащих хэши:

  • один, содержащий мои запланированные встречи с датами и, следовательно, пустой массив людей
  • , содержащий людей, приглашенных на встречу
  • и последний, содержащий людей, которые отказались

Это материализуется как:

meetings = [
 {:id=>"1", :peoples=>[]}
 {:id=>"2", :peoples=>[]}
 {:id=>"3", :peoples=>[]}
]

invited_peoples = [
 {:id=>"1", :peoples=>['Tom', 'Henry', 'Georges', 'Nicolas']}
 {:id=>"2", :peoples=>['Arthur', 'Carl']}
]

absent_peoples = [
 {:id=>"1", :peoples=>['Henry', 'Georges']}
]

И я хотел бы иметь: встречи + приглашенные люди - отсутствующие люди вроде

meetings_with_participants = [
 {:id=>"1", :peoples=>['Tom', 'Nicolas']}
 {:id=>"2", :peoples=>['Arthur', 'Carl']}
 {:id=>"3", :peoples=>[]}
]

Я ищу удобочитаемое решение, но никого не нахожу ...

Извините за мой английский sh и заранее спасибо, Николас

Ответы [ 2 ]

1 голос
/ 04 мая 2020

Определите метод для поиска объекта по идентификатору

def find_by_id array_of_hash, id
  array_of_hash.find {|x| x[:id] == id} || {peoples: []}
end

Используйте карту, чтобы превратить новый массив, внутри блока карты просто используйте свою логику c meetings + invited_peoples - absent_peoples like

result = meetings.map do |item|
  id = item[:id]
  {id: id, peoples: item[:peoples] + find_by_id(invited_peoples, id)[:peoples] - find_by_id(absent_peoples, id)[:peoples]}
end

Результат:

=> [{:id=>"1", :peoples=>["Tom", "Nicolas"]}, {:id=>"2", :peoples=>["Arthur", "Carl"]}, {:id=>"3", :peoples=>[]}]

1 голос
/ 03 мая 2020

Создание простого га sh

h = meetings.each_with_object({}) { |g,h| h[g[:id]] = g[:peoples] }
  #=> {"1"=>[], "2"=>[], "3"=>[]}

Добавление приглашенных

invited_peoples.each { |g| h[g[:id]] += g[:peoples] }

Сейчас

h #=> {"1"=>["Tom", "Henry", "Georges", "Nicolas"],
  #    "2"=>["Arthur", "Carl"], "3"=>[]} 

Удалить отклонения

absent_peoples.each { |g| h[g[:id]] -= g[:peoples] }          

Сейчас

h #=> {"1"=>["Tom", "Nicolas"], "2"=>["Arthur", "Carl"],
  #    "3"=>[]} 

Преобразовать ха sh в массив хешей

h.map { |k,v| { :id=> k, :peoples=> v } }
  #=> [{:id=>"1", :peoples=>["Tom", "Nicolas"]},
  #    {:id=>"2", :peoples=>["Arthur", "Carl"]},
  #    {:id=>"3", :peoples=>[]}] 

Сначала я создал ха sh, и только после обработки приглашенных и отклонившихся я преобразовал его в массив хэшей. Делая это таким образом, вы ускорили :id поиска для добавления и удаления людей. Как следствие, если n = meetings.size, эти вычисления имеют вычислительную сложность, близкую к O (n), «близкую к», потому что поиск ключей по ha sh имеет вычислительную сложность, почти равную O (1) (то есть время необходимо найти ключ, и его значение почти постоянно, независимо от размера га sh). Напротив, методы, которые ищут значение :id в invited_peoples и absent_peoples для каждого элемента meetings, имеют вычислительную сложность O (n 2 ).

...