2011-11-08 8 views
0

내가이 같은 블록을 말해봐 : Ruby 각 블록에서 블록 내의 배열에있는 마지막 레코드까지 어떻게 처리합니까?

<% @help_sections.each do |section| %> 
    <li><%= section.name %></li> 
<% end %> 

그러나 마지막 레코드가 반환에 뭔가 다른, 예를 들어, 작업을 수행 할

거기 년대 li에 클래스를 적용 :

<li class="last"><%= section.name %></li>

을 어떻게해야합니까 그 가장 DRY 방법?

감사합니다.

EDIT1 :

나는 블록 내에서 그렇게하는 방법을 잘 나는 단순히 if 문과 last 루비 방법을 사용하는 것이 상상,하지만? 그 배열의 마지막 요소를 원한다면 나는 단지 @help_sections.last을 할 수 있지만 Ruby 블록의 범위 내에서는 이해가되지 않는다는 것을 알고 있습니다.

답변

7

가장 좋은 방법은 대신 CSS를 사용하는 것입니다. 예를 들어. 이 :

li.last { color: red; } 

.. 그리고 다음 별도의 CSS 클래스와 마크 업을 어지럽히고, 단지 :last-child pseudoselector을 사용, 예 :

다음
li:last-child { color: red; } 

당신이보기에 아무것도 변경할 필요가 없습니다 . 이것은 IE9를 포함한 모든 최신 브라우저에서 지원됩니다.

+0

모든 주요 브라우저가': last' 및': last-child' 가상 클론을 지원합니까? 나는이 제안을 좋아한다. – marcamillion

+0

@Jordan @marcamillion 문제가 마지막'li' 스타일에 관한 것이라면 이것은 완벽한 대답이었을 것입니다. 그러나 질문은 'each' 반복자를 사용하여 파싱 된 배열의 마지막 레코드에서 특별한 것을하는 것에 관한 것입니다. 적어도 이것은 질문의 제목과 마지막으로'li '에 대한'li'와'class'가 예제로 주어 졌다는 사실에서 이해할 수 있습니다 ('.... .... '참조) –

+0

이것을보십시오 참고 문헌 : http://reference.sitepoint.com/css/pseudoclass-lastchild 및 http://www.quirksmode.org/css/contents.html. ': last-child'는 IE (9까지 버전)를 제외한 모든 주요 브라우저에서 지원됩니다. – WarHog

1

each 대신 each_with_index을 사용하면 블록에 컬렉션의 현재 요소 인덱스도 전달됩니다. 그런 다음이를 @help_sections.length과 비교할 수 있습니다.

예.

<% @help_sections.each_with_index do |section, i| %> 
    <li<% concat " class='last'" if i == @help_sections.length - 1 %>><%= section.name %></li> 
<% end %> 
+0

'each_with_index '는 레일에서 사용할 수 있습니까?왜냐하면 루비 코어에 있지 않기 때문입니다. –

+1

http://www.ruby-doc.org/core-1.9.3/Enumerable.html#method-i-each_with_index – tokland

+0

CSS 솔루션은 내가 원하는 것에 대해 가장 우아합니다. 하나 ...하지만 ... 당신은 (비슷한 성격의) 다른 문제에 대한 해결책을 가지고 있다고 생각합니까? - http://stackoverflow.com/questions/8044038/how-do-i-detect-if-a-link-has-been-clicked-and-apply-a-different-css-class-if-it – marcamillion

1

당신은

<% @help_sections.count.times do |i| %> 
    <%= @help_sections[i].name %> 
    <%= do_something if @help_sections.count == i - 1 %> 
<% end %> 
+0

CSS 솔루션은 내가 원했던 것 중 가장 우아합니다 ...하지만 ... 당신이 가지고있는 또 다른 문제 (비슷한 성격의)에 대한 해결책을 가지고 있다고 생각합니까? - http://stackoverflow.com/questions/8044038/how-do-i-detect-if-a-link-has-been-clicked-and-apply-a-different-css-class-if-it – marcamillion

1

이 오래된 답변이 도움이 될 수 있습니다 (Tell the end of a .each loop in ruby) 같은 것을 할 수있는 중. 기본적으로, 당신은 사용할 수 있습니다

<% @help_sections.each_with_index do |section, index| %> 
    <% if index == @help_sections.size - 1 %> 
    <li class="last"> 
    <% else %> 
    <li> 
    <% end %> 

    <%= section.name %></li> 
<% end %> 
+0

I 이것에 대해 생각해 보았지만 루프의 복잡성을 높이는 것처럼 들립니다. 즉, 모든 사이클에서 배열 자체에 대한 또 다른 검사를하고 있다면 배열 크기가 크면 성능에 영향을 줄 수 있습니다. – marcamillion

+0

그다지 느리지는 않습니다. 나는'[ 'Random', 'titles', 'stuffs']'가 1000 번 반복 된 배열을 포함하는 배열에서 1.9.1의 빠른 벤치 마크를 실행했고'.size - 1'에 대한 검사로는 .0001 초 그것없이. – William

+0

CSS 솔루션은 내가 원했던 것에 비해 가장 우아합니다 ...하지만 ... 내가 가지고있는 다른 비슷한 문제의 해결책을 가지고 있다고 생각합니까? - http://stackoverflow.com/questions/8044038/how-do-i-detect-if-a-link-has-been-clicked-and-apply-a-different-css-class-if-it – marcamillion

2

each_with_index보십시오 : 스마트 CSS 선택기에 포함되지 일반적인 경우

<% @help_sections.each do |section, index| %> 
    <li <%= "class='last'" if index == (@help_sections.length-1) %>><%= section.name %></li> 
<% end %> 
+0

CSS 솔루션은 내가 원했던 것에 대해 가장 우아합니다 ...하지만 ... (비슷한 성격의) 다른 문제에 대한 해결책을 가지고 있다고 생각합니까? - http://stackoverflow.com/questions/8044038/how-do-i-detect-if-a-link-has-been-clicked-and-apply-a-different-css-class-if-it – marcamillion

1

을, 당신은 그 문맥에 각각의 반복 요소를 제공 할 수있는 편리한 도우미 메서드를 정의 할 수 있습니다 컬렉션 내에서. 하나 같이 :

-each_with_context(@help_sections) do |section, context| 
    %li{:class => context[:last] ? 'last' : nil} 
    =section.name 
+0

이것에 대한 ...이 특정 문제에 대한 BIT 잔인 함이 보인다,하지만이게 내가 가지고있는 또 다른 문제에 대한 적절한 것 같아요 : http://stackoverflow.com/questions/8044038/how-do-i-detect -if-a-link-has-been-click-and-a-different-css-class-if-it 그 중 하나를 찌르는 데주의해야합니까? – marcamillion

+0

당신이 한 곳에서 그것을 사용한다면 그것은 과도 할 것입니다, 나는 동의합니다. 그러나 꽤 일반적인 것이고, 평균적인 웹 애플리케이션에서 여기저기서 유용 할 수 있다고 생각합니다. 그냥 애플리케이션 도우미에 넣으십시오. –

1

DRY는 일반적으로 좋은 생각이지만, 리튬 반복을 막기 위해 자신을 죽이지 않습니다

def each_with_context enum 
    length = enum.count 
    enum.each_with_index do |elem, i| 
    context = { 
     :first => i == 0, 
     :last => i == length - 1, 
     :even => i.even?, 
     :odd => i.odd?, 
     :middle => i == length/2 
    } 
    yield elem, context 
    end 
end 

그리고 HAML 내에서 사용이 같이 볼 수 있습니다.

<% @help_sections[0...-1].each do |section| %> 
    <li><%= section.name %></li> 
<% end %> 
<li class="last"><%= @help_sections.last.name %></li> 
관련 문제