当字符串匹配标记时删除数组元素

时间:2012-03-13 18:54:03

标签: ruby arrays ruby-on-rails-3

如果该数组中的值与给定字符串匹配,我试图从数组中删除元素。

我有一个带有标签数组的数组。我正在比较标签的名称,以查看它们是否与用户希望从搜索中排除的内容相匹配。如果是的话,我想从主数组中删除该元素,否则可能添加不匹配的元素。

这是我到目前为止所做的:

results = Array.new
test = 0
no_tags.each do |no_tag| #an array of tags whose resources are not to be included
  resources.each do |r|
    add_to_array = false
    r.tags.each do |t|
      if t.name.eql? no_tag
        test += 1
        add_to_array = false
      else
        add_to_array = true
      end
    end

    if add_to_array
      results << r
    end
  end
end 

test 变量只是一个变量,用于调试匹配事件的数量,恰好是763个资源中的141个。但是当我在运行此块之后执行results.count时,我只得到732,这时我应该得到622。

澄清一下,如果tags数组包含匹配项,我需要删除资源数组的元素,或者如果找不到匹配项,则另一个选项是将资源数组元素包含到新数组中。

这将作为JSON返回给浏览器,我需要排除其标签与no_tags数组的值匹配的资源。

4 个答案:

答案 0 :(得分:2)

您可以测试名称和no_tags的交集。它应该是空的。

results = resources.select do |r|
  (r.tags.map(&:name) & no_tags).empty?
end

答案 1 :(得分:1)

@steenslag给了我一个为我的问题提供解决方案的想法。

resources.delete_if do |resource| 
  (resource.tags.map(&:name) & no_tags).present? 
end

答案 2 :(得分:0)

您在作为黑名单元素的资源中为每个标记递增test,但结果计数是在计算资源的数量保持。假设每个资源有多个标记,那么你就算是过多了。

如果您的目的是排除每个至少有一个标记与您的黑名单匹配的资源对象,则不应将内部循环中的add_to_array设置为true。这是一个更像红宝石的尝试(注意:未经测试)

results = Array.new
test = 0
resources.each do |r|
  # are any tags elements of no_tags?
  if (r.tags & no_tags).blank? # "&": set intersection
    results << r
  else
    test += 1
  end
end

答案 3 :(得分:0)

delete_if怎么样?

resources.delete_if! { |r| (r.tags & no_tags).present? }