array = ["Spam is bad", "Ham is good"]
Chciałbym wybrać element (y) z tablicy, która zawiera (s) słowo "good" i ustawić ciąg do nowej zmiennej. Jak mogłem to zrobić?Zmień wszystkie elementy tablicy zawierające określony ciąg
array = ["Spam is bad", "Ham is good"]
Chciałbym wybrać element (y) z tablicy, która zawiera (s) słowo "good" i ustawić ciąg do nowej zmiennej. Jak mogłem to zrobić?Zmień wszystkie elementy tablicy zawierające określony ciąg
To prawie jak wpisałeś swój tytuł:
array.select {|s| s.include? "good"}
oto doc: http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-select
Istnieje także specjalna metoda to:
array.grep(/good/) # => ["Ham is good"]
Z #grep można zrobić dużo, ponieważ wymaga regularnego wyrażenia ...
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 }
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
Dobra odpowiedź, ale zauważ, że OP nigdy nie powiedział nic o zmianie ciągu ('gsub'), ale zastąpił to hurtowo. – Phrogz
@Phrogz pytanie jest bardzo niejasne co do tego, co należy ustawić na – maprihoda
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
Nie rozwiązuje to problemu z ustawieniem elementu tablicy na inną wartość. – cvshepherd
@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
@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