2010-03-25 1 views
6

이 내용은 Javascript (jQuery)로 구현되지만 모든 언어로이 메서드를 사용할 수 있다고 가정합니다.배열을 정렬 할 수 있지만 배열의 같은 위치에 보관할 특정 요소를 제외하려면 어떻게해야합니까?

나는 배열이있어서 정렬을 수행해야합니다. 배열에는 동일한 위치 (동일한 색인)로 유지되어야하는 항목이 있습니다.

배열은 <li> 요소의 목록으로 작성되며 정렬 할 값으로 목록 항목에 첨부 된 .data() 값을 사용하고 있습니다.

어떤 접근 방식이 가장 좋을까요?

나는 다음과 같은 결과 정렬 된 목록을 원하는
<ul id="fruit"> 
    <li class="stay">bananas</li> 
    <li>oranges</li> 
    <li>pears</li> 
    <li>apples</li> 
    <li class="stay">grapes</li> 
    <li>pineapples</li> 
</ul> 

<script type="text/javascript"> 
    var sugarcontent = new Array('32','21','11','45','8','99'); 
    $('#fruit li').each(function(i,e){ 
     $(this).data('sugar',sugarcontent[i]); 
    }) 
</script> 

...

<ul id="fruit"> 
     <li class="stay">bananas</li> <!-- score = 32 --> 
     <li>pineapples</li> <!-- score = 99 --> 
     <li>apples</li> <!-- score = 45 --> 
     <li>oranges</li> <!-- score = 21 --> 
     <li class="stay">grapes</li> <!-- score = 8 --> 
     <li>pears</li> <!-- score = 11 --> 
    </ul> 

감사합니다!

답변

6

알고리즘은 다음과 같습니다

  • 추출 및 stay
  • 병합 stay 사항을 표시하지 항목을 정렬 및 분류 항목

    var sugarcontent = new Array(32, 21, 11, 45, 8, 99); 
    
    var items = $('#fruit li'); 
    
    items.each(function (i) { 
        $(this).data('sugar', sugarcontent[i]); 
        // Show sugar amount in each item text - for debugging purposes 
        if ($(this).hasClass('stay')) 
         $(this).text("s " + $(this).text()); 
        else 
         $(this).text(sugarcontent[i] + " " + $(this).text()); 
    }); 
    
    // Sort sortable items 
    var sorted = $(items).filter(':not(.stay)').sort(function (l, r) { 
        return $(l).data('sugar') - $(r).data('sugar'); 
    }); 
    
    // Merge stay items and sorted items 
    var result = []; 
    var sortedIndex = 0; 
    
    for (var i = 0; i < items.length; i++) 
        if (!$(items[i]).hasClass('stay')) { 
         result.push(sorted[sortedIndex]); 
         sortedIndex++; 
        } 
        else 
         result.push(items[i]); 
    
    // Show result 
    $('#fruit').append(result); 
    
+0

이것은 내가 옳은 것으로 기록한 코드와 비슷합니다. petersendidit에서 제공하는 솔루션도 좋습니다 (테스트되지 않았지만). 감사! – calumbrodie

0

베번는 지적이 작동하지 않습니다,하지만 난 교육 목적으로 이곳을 떠날 것이다 :

$('#fruit li').sort(function(a, b) { 
    return ($(a).hasClass('stay') || $(b).hasClass('stay')) 
     ? 0 : (a.data('sugar') > b.data('sugar') ? 1 : -1); 
}).appendTo('#fruit'); 

참고 : 이름 인수로 '설탕'으로 당 데이터를 설정해야합니다

.data('sugar', sugarcontent[i]); 
+3

이 방법의 문제는 그 고정 항목입니다 정렬에 장애물이됩니다. 고정 소수점 아래의 항목은 결코 그 위에 이동하지 않으며 반대의 경우도 마찬가지입니다. – Bevan

+0

구문 오류를 지적하면서 위의 예제 코드를 수정했습니다. – calumbrodie

1

솔루션이 일반적이고 모든 개발 환경에 적용 할 수 있다고 생각하는 것이 옳습니다.

요소 목록을 두 개의 다른 목록 (분류 할 목록과 적절한 위치에 두는 목록)으로 분할해야합니다. 그런 다음 첫 번째 목록을 정렬하고 두 번째 목록과 병합하십시오.

중요한 문제는 다음과 같습니다. 대부분의 프레임 워크에서 가장 일반적인 알고리즘 인 QuickSort을 비롯한 대부분의 정렬 알고리즘은 비교 기능이 항목 위치와 같은 외부 상태 (예 :).

+0

jQuery 병합 기능을 사용하거나 배열과 리조트를 연결해야합니까? 인덱스가 동일한 경우 '고정 된'항목 배열이 우선 순위를 갖도록하려면 어떻게해야합니까? 당신이 제안한 해결책은 정확히 처음 시도 할 때 시도한 방법 이었지만 제대로 작동하지는 못했습니다. 적어도 나는 옳은 길에 있다는 것을 압니다.귀하의 의견을 보내 주셔서 감사합니다! – calumbrodie

+0

@ Konstantin의 답변은 나에게 좋을 것 같습니다. (내 자바 스크립트는 작업까지는 +1이 아닙니다.) – Bevan

3

이 그것을 수행해야합니다

var sugarcontent = new Array('32','21','11','45','8','99'); 
var list = $('#fruit'); 
var lis = list.find('li').each(function(i,e){ 
    $(this).data('score',sugarcontent[i]); 
}); 
var stay = lis.filter('.stay').each(function(){ 
    $(this).data('index',$(this).index()); 
}); 
lis.sort(function(a,b){ 
    return $(b).data('score') - $(a).data('score'); 
}).appendTo(list); 
stay.each(function(){ 
    var index = $(this).data('index'); 
    if (index == 0) { 
     list.prepend(this); 
    } else { 
     lis.filter(':eq('+index+')').insertAfter(this); 
    } 
} 

이는 클래스 숙박과 항목의 인덱스를 캐시 한 후이 점수에 의해 정렬을 수행하고 다음 클래스 항목이 다시 올바른 위치에있어 대체합니다.

관련 문제