如何输出不区分大小写的数组元素

时间:2013-05-16 15:22:36

标签: ruby

以下是测试用例

a = ["Barack", "Obama"]
b = ["John", "Obama"]

现在我做a & b。它给了我["Obama"]。常见的一个被渲染。

虽然这是场景

a = ["Barack", "Obama"]
b = ["John", "obama"] # See O is not capitalized here

我做a & b。我将得到一个空数组[]作为输出。我理解为什么。虽然,如何解决这个问题并使其区分大小写非区分大小写?

由于

更新:没有必要,它总是处于小写状态。 a可能包含字符串,b包含所有大写字符串,反之亦然。

3 个答案:

答案 0 :(得分:2)

这不是防弹的,它不会产生原始数组值,但它可能是Good Enough™:

common = a.map(&:downcase) & b.map(&:downcase)

要检索满足测试要求的原始值,您可以尝试以下方法:

require 'set'

xs = ["Barack", "Obama"]
ys = ["John", "Obama"]

univ = ys.map(&:downcase).to_set
hits = xs.select { |x| univ.include?(x.downcase) }

答案 1 :(得分:2)

这适用于更一般的情况:

class Array
  def intersection other, &block
    block ||= proc{|x| x }
    res = []
    transformed_other = other.map(&block)
    self.each do |x|
      res << x if transformed_other.include?(block.call(x))
    end
    res
  end
end

现在提供您的测试数据:

a = ["Barack", "Obama"]
b = ["John", "obama"]

您可以正常交叉数组(相当于a & b):

a.intersection(b)
#=> []

或者你可以提供一个块:

a.intersection(b, &:downcase)
#=> ["Obama"]

在这种情况下,此方法将保留第一个数组a的原始值。

答案 2 :(得分:0)

这是在两个列表的串联上使用group_by的一般方法的另一个切入点。结果包含接收器中元素的原始表示。

class Array
  def intersect_by other, &block
    (self + other).
    group_by(&block).
    values.
    select{ |v| v.size == 2 }.
    map(&:first)
  end
end

a.intersect_by(b, &:downcase)
=> ["Obama"]