Смущен многими разными способами делать одни и те же вещи
В настоящее время я работаю над курсом Ruby в Codecademy и над разделом "хэши и символы". Вот код, с которым я работаю:
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbols = []
strings.each do |x|
if x =='s'
x.to_sym!
symbols.push(x)
end
end
Цель этого кода - добавить элемент строки в переменную символов, если в строке встречается символ 's'. Однако код не проходит. Я посмотрел на решение и нашел это:
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbols = []
strings.each do |s|
s= s.to_sym
symbols.push(s)
end
Мой вопрос заключается в том, подхватывает ли Ruby фактические 's' в массиве. Это кажется жестким кодированием мне???
3 ответа
Размещенное вами решение Codeacademy на самом деле не решает проблему, которую вы объяснили. Фактическое решение будет выглядеть так
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbols = []
strings.each do |s|
if s.downcase.include? 's'
s= s.to_sym
symbols.push(s)
end
end
Кажется, что вы на самом деле пытаетесь превратить каждую строку в символ. Если это так, то выполнение каждого метода будет просто игнорировать любые "s". Чтобы увидеть, что на самом деле происходит в рабочем решении, давайте сначала разберем ваше решение.
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbols = []
strings.each do |x|
#So, if x is equal to a Class String of S
if x =='s'
#Turn that x into a symbol, which none of them should work
x.to_sym!
symbols.push(x)
end
end
Это код, который вы говорите, работает.
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbols = []
#Similar each loop, but they used s and not x
strings.each do |s|
#Instead of checking whether there is a Class String of S, it is just
#turning each value in the array into a symbol and pushing to the
#symbols array
s= s.to_sym
symbols.push(s)
end
Таким образом, суммируя, ваш код никогда не будет работать, если нет 's'
в массиве, который может быть s, но не одна строка с s. Последний работает, потому что он меняет их все без оператора if.
-edit- Я посмотрел на проблему из Code Academy и вижу, откуда возникла путаница, какова эта инструкция For each s in strings, use .to_sym to convert s to a symbol.
Это несколько сбивает с толку псевдокод, но позвольте мне переформатировать его, чтобы вы могли увидеть, где произошла путаница strings.each |s| { s = s.to_sym }
поэтому цель состоит в том, чтобы использовать s
как ваша пустая переменная. Вам не нужно было обнаруживать s
, просто используйте его как пустую переменную.
Я бы написал что-то вроде этого:
strings = ["HTML", "CSS", "JavaScript", "Python", "Ruby"]
symbols = strings.select { |s| s =~ /s/i }.map(&:to_sym)
#=> [:CSS, :JavaScript]
Объяснение:
select
выбирает все элементы массива, которые нуждаются в условии. Условие этого примера: строка s
должен соответствовать регистронезависимому регулярному выражению /s/i
(иначе строка содержит 's' или 'S'). Что сказал strings.select { |s| s =~ /s/i }
вернется ['CSS', 'JavaScript']
,
map(&:to_sym)
вернуть массив, но называется to_sym
на каждом элементе в первую очередь.
Другой вариант может быть:
symbols = strings.map { |s| s.to_sym if s =~ /s/i }.compact