Actualmente estoy trabajando en una aplicación que elimina datos de mlb.com y los datos se guardan en matrices. Luego quiero iterar sobre la matriz de datos y agregar cada elemento a un hash. Aquí hay un ejemplo de lo que estoy intentando hacer ...

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"}]

Hasta ahora, esto es exactamente lo que quiero, pero también tengo una matriz separada que almacena el número de cada jugador que estoy tratando de ingresar en cada hash con una tecla de "número" ...

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

He estado tratando de hacer esto por ...

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

Lo que finalmente me da ...

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

Entonces, el número final se está empujando en cada hash. ¿Hay una manera más fácil en la que alguien pueda pensar para empujar los números correctos donde necesitan estar? Todos los datos que estoy raspando estarán en orden.

0
B Hillsworth 10 may. 2019 a las 07:57

5 respuestas

La mejor respuesta

¿Es esto lo que estás buscando?

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

names.zip(numbers).map { |name, number| {name: name, number: number } }
1
Eneroth3 10 may. 2019 a las 09:45
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) básicamente combina elementos de self con los elementos correspondientes de cada argumento que resulta en [["Kyle Freeland", "21"], ["Jon Gray", "55"], ["DJ Johnson", "63"]].

Luego estamos iterando en esta matriz y haciendo hashes relevantes.

2
kiddorails 10 may. 2019 a las 05:18

Espero que esto te ayude.

names = ["Kyle Freeland", "Jon Gray", "DJ Johnson"]
numbers = ["21", "55", "63"]
names.zip(numbers).to_h
0
Raji 10 may. 2019 a las 05:31

Aquí hay un breve ejemplo sobre cómo resolver este problema:

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
0
Shimu 10 may. 2019 a las 05:09

Su diseño tiene algunas debilidades. Tiene dos matrices que contienen información sobre los jugadores, con el elemento i-ésimo de cada matriz perteneciente al mismo jugador. Presumiblemente, si quisiera agregar información adicional para cada jugador, como promedios de bateo, crearía una matriz de la misma longitud que los dos primeros que contenían promedios de bateo, teniendo cuidado de mantenerlos en el orden correcto. (Digo "su" porque en este momento todos los jugadores de MLB son hombres).

Ese modelo es propenso a errores. Además, ¿qué harás cuando quieras agregar datos para jugadores adicionales?

Lo primero que necesita es un identificador único para cada jugador. Por simplicidad, supongamos que ese es su nombre, reconociendo que en una aplicación real deberíamos abordar la posibilidad de que dos jugadores tengan el mismo nombre. 1 Cada vez que recolectas cada dato, debe estar asociado con el La característica de identificación del jugador, que asumimos es su nombre, por lo que no tenemos que preocuparnos por el orden de los elementos en las matrices. Por ejemplo, hagamos de nuestra base de datos un hash inicialmente vacío, players, las claves son los nombres de los jugadores y los valores son un hash que contiene información para ese jugador.

players = {}

Ahora supongamos que queremos agregar tres jugadores y sus números al hash:

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

Entonces podemos hacer lo siguiente:

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"}}

Lo primero que hace add_data es ver si el hash players tiene una clave player (por ejemplo, "Kyle Freeland"). Si no lo hace, agrega esa clave a players y establece su valor en un hash vacío. Luego fusiona el valor de player, datum, con el valor de player en players. Consulte el documento Hash # update, que es lo mismo que Hash#merge!.

Ahora supongamos que queremos agregar datos para un nuevo jugador, agregar promedios de bateo para estos tres jugadores y corregir el número de Jon Gray, que debería ser "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}} 

No quiero sugerir que esto es lo que debe hacer, simplemente que es uno de los muchos diseños que podría emplear para hacer que el análisis de datos sea más confiable y fácil de usar que su enfoque actual. De hecho, si este fuera el mundo real, sin duda querría usar una base de datos SQL para esta aplicación.

Por cierto, todos sus campos son cadenas. Eso, por supuesto, no es necesario. Ingresé los promedios de bateo como números enteros, lo que facilitaría cálculos como determinar el promedio de bateo promedio de los jugadores durante, por ejemplo, cinco años. (Quizás las carrozas, como 0.302, serían aún mejores). Además, intente usar símbolos para las teclas (por ejemplo, :avg=>312, que también puede escribir avg: 312). Además de guardar las pulsaciones del teclado, hay otras ventajas en las que no voy a entrar ahora. En general, use símbolos para las teclas tanto como sea posible.

1. En 1934, por ejemplo, los Cachorros tenían un segunda base llamado Zaphod Beeblebrox y los Yankees tenían un jardinero con el mismo nombre.

1
Cary Swoveland 10 may. 2019 a las 06:39