2011-12-03 24 views

Odpowiedz

2

Istnieje także specjalna metoda to:

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

Z #grep można zrobić dużo, ponieważ wymaga regularnego wyrażenia ...

+2

Nie rozwiązuje to problemu z ustawieniem elementu tablicy na inną wartość. – cvshepherd

+2

@maprihoda Zauważ, że podczas gdy 'grep' jest wygodny, nic nie stoi na przeszkodzie, aby użyć wyrażeń regularnych z' select' lub 'find' (jak w mojej odpowiedzi). Rzeczywiście, możesz zrobić ** znacznie więcej ** za pomocą metod blokowania, np. 'wybierz {| s | s = ~/good/i && s.length> 3} '. – Phrogz

+0

@Phrogz znacznie więcej pod względem wyrażenia regularnego; niemniej jednak masz rację, możesz dużo zrobić z select, drugi przykład w twoim komentarzu bardzo ładnie to ilustruje – maprihoda

13

Ponieważ żadna odpowiedź Dotychczas instruuje cię, jak zaktualizować ciąg w tablicy do nowej wartości, oto kilka opcji:

# 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") 

Jednak wszystkie powyższe zmieni każde wystąpienie łańcucha. Na przykład:

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... 

Jeśli nie chcesz tego skutkiem ubocznym, jeśli chcesz zastąpić ciąg w tablicy z innym napisu, ale nie zmiana ciąg samo-to trzeba znaleźć indeks elementu i aktualizacji, która:

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

Wreszcie, najprostszy i najczęściej najszybciej, bez mucking z indeksów:

# 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! brzmi jak dobry wybór.

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

Dobra odpowiedź, ale zauważ, że OP nigdy nie powiedział nic o zmianie ciągu ('gsub'), ale zastąpił to hurtowo. – Phrogz

+2

@Phrogz pytanie jest bardzo niejasne co do tego, co należy ustawić na – maprihoda

+0

Maprihoda jest poprawna. OP mówi, że 'ustawia ciąg do nowej zmiennej'. Dla wszystkich wiemy, że może to oznaczać, że tworzymy wartość całkowitą z ciągu. Może rzeczywiście wymagać wymiany, ale nie jest to wyraźnie określone. Ze względu na niejednoznaczność nie podjąłem żadnych przypuszczeń co do dokładnych intencji modyfikacji zmiennych i dostarczyłem metodę, której zawartość można było łatwo zmodyfikować zgodnie z własnymi upodobaniami. Zwróć uwagę na nazwę metody 'change_string_to_your_liking' oraz komentarz' # lub cokolwiek innego planujesz zrobić z s'. – kikuchiyo

Powiązane problemy