Идиоматическое удаление элементов списка в скобках
Как создать новый список, в котором есть все элементы старого списка, за исключением некоторых частей, заключенных в скобки между строкой, где f1(start_line) - true, а f2(end_line) - true
Наивный код
def remove_bracketted(orig_list)
ignore_flag = false
new_list = []
orig_list.each do |v|
if f1(v)
ignore_flag = true
elsif f2(v)
ignore_flag = false
else
new_list << v unless ignore_flag
end
end
end
Например, со следующими определениями f1 и f2
def f1(v)
v == "{"
end
def f2(v)
v == "}"
end
когда бежать на
foo(a,b)
{
s1
s2
s3
}
bar(a,b)
{
t1
t2
t3
}
Какой-то другой текст
надо получить
foo(a,b)
bar(a,b)
Some other text
Пожалуйста, обратите внимание, что f1
а также f2
может быть любой функцией типа a
-> Bool, где все элементы списка имеют тип a
а не просто сравнение с открытой и закрытой скобками.
Изменить: я искал решение, как это, которое работает, если есть только одна такая пара
new_list = old_list.take_while(not(condition1)).concat(old_list.drop_while(not(condition2)))
2 ответа
Это может быть место, где оператор триггера будет полезен:
def val1; '{' end
def val2; '}' end
p ['a','b','{','a','}','f','d','d'].reject{|x| true if (val1==x)..(val2==x)}
#=> ["a", "b", "f", "d", "d"]
p ['a','b','{','a','}','f','d','d'].select{|x| true if (val1==x)..(val2==x)}
#=> ["{", "a", "}"]
ScriptDevil, я полагаю, некоторым людям не понравится ваш способ задать вопрос, поэтому я предлагаю задать его более политично и не предлагать нам "задачу", как мы находимся в классе. Мы здесь, чтобы помочь, и вы должны показать нам, что вы попробовали сами.
Вот способ сделать то, что вы хотите.
class String
def replace_between start, ending, replace_with
gsub(/#{start}[^#{ending}]*#{ending}/m, replace_with)
end
end
txt = %[
foo(a,b)
{
s1
s2
s3
}
bar(a,b)
{
t1
t2
t3
}
Some other text
]
puts txt.replace_between '{', '}', ''
# oo(a,b)
# bar(a,b)
# Some other text