以惯用方式删除括号列表元素

时间:2014-01-28 10:54:25

标签: ruby idiomatic

如何生成新列表包含旧列表的所有元素,除了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

请注意,f1f2可以是a类型的任何函数 - &gt; Bool,其中列表元素都是a类型,而不仅仅是与开括号和近括号的比较。

修改 我正在寻找一个像这样的解决方案,如果只有一个这样的一对

new_list = old_list.take_while(not(condition1)).concat(old_list.drop_while(not(condition2)))

2 个答案:

答案 0 :(得分:1)

这可能是触发器操作符有用的地方:

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", "}"]

答案 1 :(得分:0)

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