如何在Ruby中从另一个数组创建一个重复的不区分大小写的字符串数组?

时间:2014-11-10 20:18:12

标签: ruby-on-rails ruby arrays string duplicates

我有一个字符串数组。我想要更改这些重复字符串的名称以附加一个数值,使它们像这样独特......

原始数组

a, a, A, b, c, D, d

更正数组

a, a1, A2, b, c, D, d1

我已经接近以下代码;但是,如果字符串是不同的案例结构,那么它们当前不会被视为与此代码段重复。我希望它们被认为是重复的,但是在结果数组中却没有改变它们的情况。

duplicate_counter = 1
duplicates = Array.new
duplicates = file_columns.select{ |e| file_columns.count(e) > 1 } # get duplicate column names

duplicates.each{ |x| file_columns.delete(x) }
duplicates.sort!
duplicates.each_with_index do |d, i|

  if i > 0
     if d == duplicates[i-1]
        d = d.strip + duplicate_count.to_s
        duplicate_count += 1
     else 
        duplicate_count = 1
     end
  end

  # Add back the column names, but with the appended numerical counts to make them unique
  file_columns.push(d)
end

2 个答案:

答案 0 :(得分:3)

你过度思考它。我确信有更好的方法可以做到这一点,但它完成了工作。

a = ['a', 'a', 'A', 'b', 'c', 'D', 'd']
letters = Hash.new(-1)
a.map do |letter|
  l = letter.downcase
  letters[l] += 1
  if (letters[l] > 0)
    "#{letter}#{letters[l]}"
  else
    "#{letter}"
  end
end

答案 1 :(得分:1)

如果不依赖于案例的字母不一定分组,那么这是一种方法。例如,它将转换此数组:

arr = %w{ a D a A b c D a d }
  #=> ["a", "D", "a", "A", "b", "c", "D", "a", "d"]

为:

["a", "D", "a1", "A2", "b", "c", "D1", "a3", "d2"]

<强>代码

def convert(arr)
  arr.each_with_index
     .group_by { |c,_| c.downcase }
     .values
     .flat_map { |c|
       c.map
        .with_index { |(f,l),i| [i > 0 ? f<<i.to_s : f, l] } }
     .sort_by(&:last)
     .map(&:first)
end

示例

对于上面的arr

convert(arr)
 #=> ["a", "D", "a1", "A2", "b", "c", "D1", "a3", "d2"]

<强>解释

亲爱的读者,如果您是Ruby的新手,这可能看起来很复杂。但是,如果将其细分为步骤,那就不那么糟糕了。获得经验并熟悉常用方法后,它会很自然地出现。在这里,我使用了以下方法,链接在一起,以便每个方法的返回值成为下一个的接收方:

这里发生了什么。

enum = arr.each_with_index
  #=> #<Enumerator: ["a", "D", "a", "A", "b", "c",
  #                  "D", "a", "d"]:each_with_index>
h = enum.group_by { |c,_| c.downcase }
  #=> {"a"=>[["a", 0], ["a", 2], ["A", 3], ["a", 7]],
  #    "d"=>[["D", 1], ["D", 6], ["d", 8]],
  #    "b"=>[["b", 4]],
  #    "c"=>[["c", 5]]}
a = h.values
  #=> [[["a", 0], ["a", 2], ["A", 3], ["a", 7]],
  #    [["D", 1], ["D", 6], ["d", 8]],
  #    [["b", 4]],
  #    [["c", 5]]]
b = a.flat_map { |c| c.map.with_index { |(f,l),i| [i > 0 ? f<<i.to_s : f, l] } }
  #=> [["a", 0], ["a1", 2], ["A2", 3], ["a3", 7], ["D", 1],
  #    ["D1", 6], ["d2", 8], ["b", 4], ["c", 5]]
c = b.sort_by(&:last)
  #=> [["a", 0], ["D", 1], ["a1", 2], ["A2", 3], ["b", 4],
  #    ["c", 5], ["D1", 6], ["a3", 7], ["d2", 8]]
c.map(&:first)
  #=> ["a", "D", "a1", "A2", "b", "c", "D1", "a3", "d2"]