2013-03-25 2 views
4

이 주제를 다루는 많은 질문/답변이 있습니다. 내 구체적인 사례는 없습니다. 희망 누군가가 도움이 될 수 있습니다자바 스크립트에서 배열 재정렬

var indexes = [24, 48, 32, 7, 11]; 

그리고 여기에 유사 객체의 배열 :

내가 같은 인덱스의 배열을 가지고

var items = [{ 
       name : "whatever", 
       selected : false, 
       loading : true, 
       progress : 55, 
       complete : false 
}, 
{ 
       name : "whatever 2", 
       selected : false, 
       loading : false, 
       progress : 100, 
       complete : true 
}]; 

indexes 배열 대응의 각 정수 items 배열 내의 객체의 실제 색인에 적용됩니다. indexes에 저장된 인덱스를 가지고있는 항목 배열의 모든 objects을 위해 내가하고 싶은 무엇

var insertindex = ?? 

은 다음과 같습니다

마지막으로 나는 항목 배열 내에서 새로운 삽입 위치를 정의하는 변수가 배열을 제거한 다음 제거하고 마지막으로 변수를 insertindex에 의해 정의 된 지정된 색인에 서로 나란히 놓습니다.

각 색인의 개체를 임시 배열로 복사 한 다음 원래 배열에서 제거하고 마지막으로이 임시 배열을 반복하여 원래 항목 배열에 다시 넣어서 사용하려고 시도했습니다. 새로운 위치에 있지만 정신 벽돌 벽을 치고있는 것처럼 보이며 제대로 작동하지 않습니다.

간단히 요약하면 인덱스 배열에 정의 된 인덱스와 일치하는 items 배열의 모든 객체를 가져 와서 미리 정의 된 인덱스에 다시 삽입하여 items 배열에 다시 넣기 만하면됩니다.

개념적 시각화를 돕기 위해. 앱을 자바 스크립트 파일 관리자로 생각하면 인접하지 않아도되는 여러 파일 선택을 재정렬 할 수 있습니다. 현재 선택을 정의하는 indexes 배열과 파일 목록을 정의하는 items 배열. 마지막으로 rearoderindex은 선택한 모든 파일을 이동해야하는 새로운 삽입 위치를 정의합니다.

편집 :

function reorder(items, indexes, insertindex){ 

     var offset = 0; 
     var itemscopy = items.slice(0); //make shallow copy of original array 
     var temparray = new Array(); // create temporary array to hold pulled out objects 

     //loop through selected indexes and copy each into temp array 
     for(var i=0, len=indexes.length; i<len; i++){ 
      array[i] = itemscopy[self.cache.selecteditems[i]]; 
     } 


     //remove all selected items from items array 
     for(var i=0, len=indexes.length; i<len; i++){ 
      items.splice(indexes[i], 1); 
     } 

     //finally loop through new temp array and insert the items back into the items array at the specified index, increasing the index each iteration using the offset variable. 
     for(var i=0, len=temparray.length; i<len; i++){ 
      items.splice((insertindex+offset), 0, array[i]); 
      offset++; 
     } 

} 

나는이 꽤 끔찍 알고 있어요 세 번 반복하는 것이 필요하지 않을 것을 : 바로 여기에 제안 된 바와 같이 내가 지금 함께 연주하고있는 코드입니다. 그러나 나는 많은 다른 방법을 시도해 왔습니다. 어떤 것은 한 방향으로 재 배열 할 때, 다른 방향으로 재 배열 할 때, 다른 한 방향으로 재 배열 할 때 작동합니다. 내가 정확성을 가지고 작업하게되면 나중에 함수를 최적화 할 것이라고 생각했습니다.

나는 무언가를 극도로 어리 석거나 완전히 바라보고있을 것임에 틀림 없다. 그러나 내 인생에서 나는 지금 무엇을 해결할 수 없는지 확신한다.

+4

JSFiddle을 만들거나 더 나은 아직은 스플 라이스 코드를 게시하십시오. 그 말은 내게 맞는 궤적처럼 들린다. –

답변

2

.splice() 함수를 사용하면 배열에 요소를 추가하고 요소를 제거 할 수 있습니다.일반적인 원칙은 :

  1. 정렬 인덱스 (삭제 된 항목의 수를 조절)이 인덱스의 요소를 제거
  2. 대하여 반복 indexes 위에 숫자 순서 오름차순 및 removedItems 배열
  3. 추가에 저장 내로

    : 다시 코드 필요한 인덱스

에서 removedItems 배열은이 같이 보일 것입니다해야 할 일

var removedItems = []; 
// sort indexes 
indexes.sort(function(a, b) { 
    if(a < b) return -1; 
    else if(b < a) return 1; 
    return 0; 
}); 
for(var i = 0; i < indexes.length; i++) { 
    var index = indexes[i]; 
    removedItems.push(items.splice(index - removedItems.length, 1)); 
} 
var insertIndex = 1; 
items.splice.apply(items, [insertIndex, 0].concat(removedItems)); 

this jsFiddle demo을 살펴보십시오.

+0

이것은 절대적으로 완벽하게 작동합니다! :) 환상적. 시스템은 또한 최소한의 테스트 하에서도 작동하는 것으로 보이는 대답을 제공합니다. 내가 대답을 수여하기 전에 당신이 가장/가장 실적이 좋은 해결책이라고 생각하는 의견을 말할 수있는 기회는 무엇입니까? 어쨌든 많은 감사합니다. 그게 큰 도움이됩니다. – gordyr

+1

@ gordyr 그래서'indexes' 배열 요소의 순서에 신경 쓰지 않는다는 뜻입니까? – VisioN

+0

@VisioN이 경우, 아니요. 항목 (파일)은 인덱스가 증가함에 따라 왼쪽에서 오른쪽, 위에서 아래로 표시되기 때문에 오름차순으로 정렬하면 사용 사례에 대한 올바른 동작입니다. 그러나 앤서니 (Anthony)의 대답 외에도 나는 선택된'code' 인덱스 값 중 얼마나 많은 수가 'code'삽입 인덱스보다 작은 지 테스트하고 그만큼 삽입 위치를 오프셋해야한다는 것을 주목할 필요가 있습니다. 배열의 시작 부분부터 배열의 끝 부분까지 중간에있는 삽입 지점으로 구성된 파일의 선택을 재정렬 할 수 있다는 의미입니다. – gordyr

5

당신이, 내가 또 다른 짧은 솔루션을 제안 할 것 indexes 배열의 순서에 대해 상관하지 않는 경우 :

items.splice.apply(items, [insertIndex, 0].concat(indexes.sort(function(a, b) { 
    return a - b; 
})).map(function(i, p) { 
    return p > 1 ? items.splice(i - p + 2, 1).pop() : i; 
})); 

DEMO :http://jsfiddle.net/T83fB/

내가 Array.map() 방법을 사용하는이 짧은 만들려면 어떤 이전 IE 브라우저에서는 지원되지 않습니다. 그러나 항상 MDN에서 shim을 사용하는 것은 쉽습니다.

+0

이것은 사랑스럽고 매우 우아한 해결책입니다! VisioN 감사합니다. 나중에 철저히 테스트 해보고 가장 좋은 해결책으로 밝혀지면 자신에게 맞는 답을 주겠다. :) 많은 감사! – gordyr