2011-12-03 6 views

Respuesta

2

También hay un método especial para esto:

array.grep(/good/) # => ["Ham is good"] 

Con #grep se puede hacer una mucho porque toma una expresión regular ...

+2

Esto no resuelve el problema de establecer el elemento de matriz en otro valor. – cvshepherd

+2

@maprihoda Tenga en cuenta que aunque 'grep' _is_ convenient, nada le impide usar una expresión regular con' select' o 'find' (como en mi respuesta). De hecho, puede hacer ** mucho más ** con los métodos de bloque, p. 'select {| s | s = ~/good/i && s.length> 3} '. – Phrogz

+0

@Phrogz mucho más en términos de expresión regular; sin embargo, tienes razón, puedes hacer mucho con select, el segundo ejemplo de seleccionar en tu comentario lo ilustra muy bien – maprihoda

13

Como ninguna respuesta hasta el momento se instruye sobre cómo actualizar la cadena de la matriz con el nuevo valor, aquí hay algunas opciones:

# Find every string matching a criteria and change them 
array.select{ |s| s.include? "good" }.each{ |s| s.replace("bad") } 

# Find every string matching a pattern and change them 
array.grep.replace("bad").each{ |s| s.replace("bad") } 

# Find the first string matching a criteria and change it 
array.find{ |s| s =~ /good/ }.replace("bad") 

Sin embargo, todo lo anterior va a cambiar todas las instancias de una cadena. Por ejemplo:

jon = Person.new "Johnny B. Goode" 
array = [ jon.name, "cat" ] 
array.find{ |s| s =~ /good/i }.replace("bad") 

p array #=> "bad" 
p jon #=> #<Person name="bad"> Uh oh... 

Si no quieren este lado efecto, si desea reemplazar la cadena de la matriz con una cadena dediferente, pero no cambio la propia cadena, entonces necesita encontrar el índice del elemento y actualización que:

# Find the _first_ index matching some criteria and change it 
array[ array.index{ |s| s =~ /good/ } ] = "bad" 

# Update _every_ item in the array matching some criteria  
array[i] = "bad" while i = array.index{ |s| s =~ /good/i } 

# Another way to do the above 
# Possibly more efficient for very large arrays any many items 
indices = array.map.with_index{ |s,i| s =~ /good/ ? i : nil }.compact 
indices.each{ |i| array[i] = "bad" } 

Por último, el más simple y sobre todo más rápido, sin curioseaba con índices:

# Create a new array with the new values 
new_array = array.map do |s| 
    if s =~ /good/i # matches "Good" or "good" in the string 
    "bad" 
    else 
    s 
    end 
end 

# Same thing, but shorter syntax 
new_array = array.map{ |s| s =~ /good/i ? "bad" : s } 

# Or, change the array in place to the new values 
new_array = array.map!{ |s| s =~ /good/i ? "bad" : s } 
2

map! suena como una buena opción.

x = ['i', 'am', 'good'] 
def change_string_to_your_liking s 
    # or whatever it is you plan to do with s 
    s.gsub('good', 'excellente!') 
end 
x.map! {|i| i =~ /good/ ? change_string_to_your_liking(i) : i} 
puts x.inspect 
+0

Buena respuesta, pero ten en cuenta que el OP nunca dijo nada sobre cambiar la cadena ('gsub'), sino que reemplazó al por mayor. – Phrogz

+2

@Phrogz la pregunta es muy clara acerca de qué se debe establecer en qué – maprihoda

+0

Maprihoda es correcta. El OP dice 'establecer la cadena a una nueva variable'. Por lo que sabemos, podría significar crear un valor entero a partir de la cadena. De hecho, podría requerir reemplazo, pero esto no se establece explícitamente. Debido a la ambigüedad, no asumí las intenciones exactas de la modificación de la variable y proporcioné un método cuyos contenidos podrían modificarse fácilmente a su gusto. Tenga en cuenta el nombre del método 'change_string_to_your_liking' y el comentario' # o lo que sea que planee hacer con s'. – kikuchiyo

Cuestiones relacionadas