Цикл массива и добавление этих данных с новым ключом к хешам в отдельном массиве - PullRequest
0 голосов
/ 10 мая 2019

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

players = []

names = ["Kyle Freeland", "Jon Gray", "DJ Johnson"]

names.each do |name|
  players << {:name => name}
end

players 
=> [{:name=>"Kyle Freeland"}, {:name=>"Jon Gray"}, {:name=>"DJ 
Johnson"}]

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

numbers = ["21", "55", "63"]

Я пытался сделать это с помощью ...

numbers.each do |number|
  players.each do |player|
    player[:number] = number
  end
end

Что в конечном итоге дает мне ...

players
[{:name=>"Kyle Freeland", :number=>"63"}, {:name=>"Jon Gray", 
:number=>"63"}, {:name=>"DJ Johnson", :number=>"63"}]

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

Ответы [ 5 ]

2 голосов
/ 10 мая 2019
names = ["Kyle Freeland", "Jon Gray", "DJ Johnson"]
numbers = ["21", "55", "63"]

players = names.zip(numbers).map { |x| { name: x[0], number: x[1] } }
#=> [{:name=>"Kyle Freeland", :number=>"21"}, {:name=>"Jon Gray", :number=>"55"}, {:name=>"DJ Johnson", :number=>"63"}]

names.zip(numbers) в основном объединяет элементы self с соответствующими элементами из каждого аргумента, что приводит к [["Kyle Freeland", "21"], ["Jon Gray", "55"], ["DJ Johnson", "63"]].

Затем мы выполняем итерацию этого массива и делаем соответствующие хэши.

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

Это то, что вы ищете?

names = ["Kyle Freeland", "Jon Gray", "DJ Johnson"]
numbers = ["21", "55", "63"]

names.zip(numbers).map { |name, number| {name: name, number: number } }
1 голос
/ 10 мая 2019

У вашего дизайна есть свои недостатки.У вас есть два массива, содержащих информацию об игроках, с i-м элементом каждого массива, относящимся к одному и тому же игроку.Предположительно, если вы хотите добавить дополнительную информацию для каждого игрока, такую ​​как средние значения ватина, вы должны создать массив той же длины, что и первые два, которые содержат средние значения ватина, стараясь сохранять их в правильном порядке.(Я говорю «его», потому что в настоящее время все игроки MLB - мужчины.)

Эта модель подвержена ошибкам.Кроме того, что вы будете делать, когда хотите добавить данные для дополнительных игроков?

Первое, что вам нужно, это уникальный идентификатор для каждого игрока.Для простоты, давайте предположим, что это его имя, признавая, что в реальном приложении нам нужно учесть возможность того, что два игрока имеют одно и то же имя.идентифицирующая характеристика, которую мы предполагаем - это его имя, поэтому нам не нужно беспокоиться о порядке элементов в массивах.Например, давайте сделаем нашу базу данных изначально пустым хешем, players, ключами будут имена игроков, а значениями - хеш, содержащий информацию для этого игрока.

players = {}

Теперь предположим, что мы хотим добавитьтри игрока и их номера в хэш:

numbers = {
  "Kyle Freeland"=>{ "number"=>"21" }, 
  "Jon Gray"     =>{ "number"=>"55" },
  "DJ Johnson"   =>{ "number"=>"63" }
}

Затем мы можем сделать следующее:

def add_data(players, data)
  data.each do |player, datum|
    players[player] = {} unless players.key?(player)
    players[player].update(data[player])
  end
end

add_data(players, numbers)
players
  #=> {"Kyle Freeland"=>{"number"=>"21"},
  #    "Jon Gray"=>{"number"=>"55"},
  #    "DJ Johnson"=>{"number"=>"63"}}

Первое, что делает add_data, это проверяет, есть ли у хэша players ключ player (например, "Kyle Freeland").Если это не так, он добавляет этот ключ к players и устанавливает его значение в пустой хеш.Затем он объединяет значение player, datum со значением player в players.См. Документ Hash # update , который совпадает с Hash#merge!.

Теперь предположим, что мы хотим добавить данные для нового игрока, добавить средние значения для этих трех игроков и исправить JonНомер Грея, который должен быть «56»:

batting_average = {
  "Kyle Freeland"=>{ "avg"=>302 }, 
  "Jon Gray"     =>{ "avg"=>246 },
  "DJ Johnson"   =>{ "avg"=>280 }
}

new_player = {
  "Dusty Rhodes" =>{"number"=>"12", "avg"=>312 }
}

correction = {
  "Jon Gray"=>{ "number"=>"56" }
}

add_data(players, batting_average)
add_data(players, new_player)
add_data(players, correction)

players
  #=> {"Kyle Freeland"=>{"number"=>"21", "avg"=>302},
  #    "Jon Gray"     =>{"number"=>"56", "avg"=>246},
  #    "DJ Johnson"   =>{"number"=>"63", "avg"=>280},
  #    "Dusty Rhodes" =>{"number"=>"12", "avg"=>312}} 

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

Кстати, все ваши поля являются строками.Это, конечно, не обязательно.Я ввел средние значения ватинов в виде целых чисел, которые облегчили бы вычисления, такие как определение среднего среднего уровня игроков, скажем, за пять лет.(Возможно, поплавки, такие как 0.302, будут еще лучше).Также попробуйте использовать символы для клавиш (например, :avg=>312, который вы можете альтернативно написать avg: 312).Помимо сохранения нажатий клавиш есть и другие преимущества, которые я не буду использовать сейчас.В общем, используйте символы для ключей как можно больше.

1.Например, в 1934 году у новичков был второй человек с низов по имени Зафод Библброкс, а у янки был аутфилдер с тем же именем.

0 голосов
/ 10 мая 2019

Надеюсь, это вам поможет.

names = ["Kyle Freeland", "Jon Gray", "DJ Johnson"]
numbers = ["21", "55", "63"]
names.zip(numbers).to_h
0 голосов
/ 10 мая 2019

Вот краткий пример того, как решить эту проблему:

players = []

names = ["Kyle Freeland", "Jon Gray", "DJ Johnson"]
numbers = ["21", "55", "63"]

names.each_with_index do |name, idx|
  players << {:name => name, number: numbers[idx]}
end
...