Функция HAML .each со списком и дубликатами - PullRequest
0 голосов
/ 29 августа 2018

Я пытаюсь выяснить, как я могу распространять определенные элементы списка на основе оператора if.

Это список:

@x = ["american", "assistive", "audio", "blind", "braille", "closed-captioning", "closed-captioning", "deaf", "low", "phone", "question-circle", "question-circle", "sign", "tty", "universal", "wheelchair"]

Это мой код хамла:

        %ul.list-inline
        - @x.each do |i|
          - if i[0].length < i[1].length
            %li            
              %i{:class=>"fas fa-#{i[0]} fa-2x"}
              %span.f6 #{i[0]}                      
          - else
            %li             
              %i{:class=>"far fa-#{i[1]} fa-2x"}
              %span.f6 #{i[1]} 

То, что я пытаюсь сделать, это определить длину каждой строки в списке и сравнить ее с длиной следующей строки в списке.

Как только вторая строка определена как дубликат, она должна идти под оператором else.

Проблема, с которой я сталкиваюсь, заключается в том, что, переходя к i [0] вместо первой строки в списке, я получаю первую букву каждой строки в списке.

Я не знаю, является ли мой способ использования длины лучшим способом решения этой проблемы, поэтому, если у кого-то еще есть лучшее решение, я открыт для него, пока он выполняет свою работу.

Я думаю, что, возможно, если бы я мог отфильтровать элементы в списке на основе , какие элементы являются уникальными, а какие являются дубликатами , я мог бы затем распределить их соответствующим образом.

Но как мне это сделать?

Спасибо.

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Чтобы ответить на первую часть вашего вопроса, где i[0] или i[1] возвращает одну букву вместо элемента, давайте рассмотрим ваш код:

@x.each do |i|

Здесь i - элемент. Таким образом, в первой итерации i является «американским». Поэтому, когда вы вызываете i[0], он возвращает первый символ строки, который является a , а i[1] возвращает m , и обе их длины равны 1 .

Вместо этого вы должны изменить свой код следующим образом:

%ul.list-inline
        - @x.each_cons(2) do |current, next|
          - if current.length < next.length
            %li            
              %i{:class=>"fas fa-#{current} fa-2x"}
              %span.f6 #{current}                      
          - else
            %li             
              %i{:class=>"far fa-#{next} fa-2x"}
              %span.f6 #{next} 

Что касается второй части вашего вопроса, вы определили @x как:

@x = ["american", "assistive", "audio", "blind", "braille", "closed-captioning", "closed-captioning", "deaf", "low", "phone", "question-circle", "question-circle", "sign", "tty", "universal", "wheelchair"]

Чтобы получить уникальные элементы:

@x_uniq = @x.uniq

Чтобы получить дубликаты:

@x_dup = @x.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }.select{ |k,v| v > 1 }.keys

, который возвращает

["closed-captioning", "question-circle"]

По моему мнению, использование второго способа фильтрации данных и его использование - лучшее решение, чем сравнение элементов с их длинами.

Надеюсь, это помогло.

0 голосов
/ 29 августа 2018

Использование Enumerable#each_cons:

- @x.each_cons(2) do |cur, nxt|
  - if cur.length < nxt.to_s.length
    ...
  - else
    ...
...