Как к uniq нечувствительный к регистру массив

Щелкните правой кнопкой мыши по модулю, выберите «Добавить поддержку фреймворка ...» и проверьте технологию «Maven».

(Это также создает pom.xml для вас, чтобы изменить.)

Если вы имеете в виду добавление элементов репозитория источника, я думаю, вам нужно сделать это вручную - не уверен.

До IntelliJ 13 это не будет преобразовывать проект в Maven Standard Directory Layout , 13+ это будет.

11
задан Codebeef 9 July 2009 в 11:48
поделиться

5 ответов

Просто сначала сделайте случай последовательным.

например:

["a","A"].map{|i| i.downcase}.uniq

Edit: Если, как предлагает mikej, возвращаемые элементы должны быть точно такими же, как в исходном массиве, то это сделает это за вас:

a.inject([]) { |result,h| result << h unless result.map{|i| i.downcase}.include?(h.downcase); result }

Edit2 Решение, которое должно удовлетворить mikej: -)

downcased = [] 
a.inject([]) { |result,h| 
        unless downcased.include?(h.downcase);
            result << h
            downcased << h.downcase
        end;
        result}
16
ответ дан 3 December 2019 в 00:43
поделиться

вы можете построить отображение (хэш) между значениями, нормализованными по регистру (например, в нижнем регистре), и фактическим значением, а затем взять только значения из хеша:

["a", "b", "A", "C"]\
.inject(Hash.new){ |h,element| h[element.downcase] = element ; h }\
.values

выбирает последнее вхождение заданное слово (без учета регистра):

["A", "b", "C"]

, если вы хотите, чтобы первое вхождение:

["a", "b", "A", "C"]\
.inject(Hash.new){ |h,element| h[element.downcase] = element  unless h[element.downcase]  ; h }\
.values
7
ответ дан 3 December 2019 в 00:43
поделиться
["a", "A"].map{|x| x.downcase}.uniq
=> ["a"]

или

["a", "A"].map{|x| x.upcase}.uniq
=> ["A"]
4
ответ дан 3 December 2019 в 00:43
поделиться

Более общее решение (хотя и не самое эффективное):

class EqualityWrapper
  attr_reader :obj

  def initialize(obj, eq, hash)
    @obj = obj
    @eq = eq
    @hash = hash
  end

  def ==(other)
    @eq[@obj, other.obj]
  end

  alias :eql? :==

  def hash
    @hash[@obj]
  end
end

class Array
  def uniq_by(eq, hash = lambda{|x| 0 })
    map {|x| EqualityWrapper.new(x, eq, hash) }.
    uniq.
    map {|x| x.obj }
  end

  def uniq_ci
    eq = lambda{|x, y| x.casecmp(y) == 0 }
    hash = lambda{|x| x.downcase.hash }
    uniq_by(eq, hash)
  end
end

Метод uniq_by принимает лямбда, которая проверяет равенство, и лямбда, которая возвращает хэш, и удаляет повторяющиеся объекты, как это определено этими данными.

Реализованный поверх этого метод uniq_ci удаляет дубликаты строк, используя сравнения без учета регистра.

0
ответ дан 3 December 2019 в 00:43
поделиться

Немного более эффективный способ - использовать ключи uniq в хэшах, поэтому проверьте следующее:

["a", "A"].inject(Hash.new){ |hash,j| hash[j.upcase] = j; hash}.values

вернет последний элемент, в данном случае

["A"]

, тогда как использование || = как оператор присваивания:

["a", "A"].inject(Hash.new){ |hash,j| hash[j.upcase] ||= j; hash}.values

вернет первый элемент, в этом случае

["a"]

, особенно для больших массивов, это должно быть быстрее, поскольку мы не ищем в массиве каждый раз, используя include?

ура ...

2
ответ дан 3 December 2019 в 00:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: