[javascript] Javascript의 값으로 연관 배열을 정렬하는 방법은 무엇입니까?

연관 배열이 있습니다.

array["sub2"] = 1;
array["sub0"] = -1;
array["sub1"] = 0;
array["sub3"] = 1;
array["sub4"] = 0;

결과가 다음 순서로 각 인덱스가있는 배열이되는 값을 기준으로 정렬 (내림차순)하는 가장 우아한 방법은 무엇입니까?

sub2, sub3, sub1, sub4, sub0



답변

자바 스크립트는 당신이 생각하는 “연관 배열”이 없습니다. 대신 배열과 유사한 구문 (예제에서와 같이)을 사용하여 객체 속성을 설정하는 기능과 객체의 속성을 반복하는 기능이 있습니다.

이것의 결론은 속성을 반복 하는 순서 에 대한 보장이 없으므로 정렬과 같은 것은 없다는 것입니다. 대신 개체 속성을 “진정한”배열 (순서를 보장 함)로 변환해야합니다. 다음은 객체를 두 개의 튜플 (요소가 두 개인 배열)의 배열로 변환하고 설명하는대로 정렬 한 다음 반복하는 코드 조각입니다.

var tuples = [];

for (var key in obj) tuples.push([key, obj[key]]);

tuples.sort(function(a, b) {
    a = a[1];
    b = b[1];

    return a < b ? -1 : (a > b ? 1 : 0);
});

for (var i = 0; i < tuples.length; i++) {
    var key = tuples[i][0];
    var value = tuples[i][1];

    // do something with key and value
}

콜백을받는 함수로 래핑하는 것이 더 자연 스러울 수 있습니다.

function bySortedValue(obj, callback, context) {
  var tuples = [];

  for (var key in obj) tuples.push([key, obj[key]]);

  tuples.sort(function(a, b) {
    return a[1] < b[1] ? 1 : a[1] > b[1] ? -1 : 0
  });

  var length = tuples.length;
  while (length--) callback.call(context, tuples[length][0], tuples[length][1]);
}

bySortedValue({
  foo: 1,
  bar: 7,
  baz: 3
}, function(key, value) {
  document.getElementById('res').innerHTML += `${key}: ${value}<br>`
});
<p id='res'>Result:<br/><br/><p>


답변

‘연관 배열’의 의미를 수정하는 대신 이것이 원하는 것이라고 생각합니다.

function getSortedKeys(obj) {
    var keys = keys = Object.keys(obj);
    return keys.sort(function(a,b){return obj[b]-obj[a]});
}

위해 정말 오래된 브라우저 , 대신를 사용 :

function getSortedKeys(obj) {
    var keys = []; for(var key in obj) keys.push(key);
    return keys.sort(function(a,b){return obj[b]-obj[a]});
}

당신은 (당신과 같은) 객체를 덤프하고 키 배열을 가져옵니다-eh 속성-다시, eh, 값, eh, 객체의 (숫자) 값에 따라 내림차순으로 정렬됩니다.

값이 숫자 인 경우에만 작동합니다. Tweek는 function(a,b)정렬 메커니즘을 변경하여 오름차순으로 작동하거나 string값에 대해 작동 합니다 (예 :). 독자를위한 연습 문제로 남았습니다.


답변

값을 기준으로 (연관) 배열을 정렬하는 방법에서 다루는 계속되는 토론 및 기타 솔루션 내 경우에 가장 좋은 해결책은 saml (아래 인용)입니다.

배열은 숫자 인덱스 만 가질 수 있습니다. 이것을 Object 또는 Array of Objects로 다시 작성해야합니다.

var status = new Array();
status.push({name: 'BOB', val: 10});
status.push({name: 'TOM', val: 3});
status.push({name: 'ROB', val: 22});
status.push({name: 'JON', val: 7});

status.push방법 이 마음에 들면 다음과 같이 정렬 할 수 있습니다.

status.sort(function(a,b) {
    return a.val - b.val;
});


답변

실제로 JavaScript에는 “연관 배열”과 같은 것이 없습니다. 당신이 가진 것은 단지 평범한 오래된 물건입니다. 물론 그들은 일종의 연관 배열처럼 작동하며 키는 사용할 수 있지만 키 순서에 대한 의미는 없습니다.

객체를 객체 배열 (키 / 값 쌍)로 바꾸고 정렬 할 수 있습니다.

function sortObj(object, sortFunc) {
  var rv = [];
  for (var k in object) {
    if (object.hasOwnProperty(k)) rv.push({key: k, value:  object[k]});
  }
  rv.sort(function(o1, o2) {
    return sortFunc(o1.key, o2.key);
  });
  return rv;
}

그런 다음 비교기 기능으로 호출합니다.


답변

튜플이 마음에 들지 않으면 벤 블랭크의 대답을 변형 한 것입니다.

이렇게하면 몇 개의 문자가 절약됩니다.

var keys = [];
for (var key in sortme) {
  keys.push(key);
}

keys.sort(function(k0, k1) {
  var a = sortme[k0];
  var b = sortme[k1];
  return a < b ? -1 : (a > b ? 1 : 0);
});

for (var i = 0; i < keys.length; ++i) {
  var key = keys[i];
  var value = sortme[key];
  // Do something with key and value.
}


답변

불필요한 합병증이 필요하지 않습니다 …

function sortMapByValue(map)
{
    var tupleArray = [];
    for (var key in map) tupleArray.push([key, map[key]]);
    tupleArray.sort(function (a, b) { return a[1] - b[1] });
    return tupleArray;
}


답변

나는 $ .each of jquery를 사용하지만 for 루프로 만들 수 있습니다. 개선 사항은 다음과 같습니다.

        //.ArraySort(array)
        /* Sort an array
         */
        ArraySort = function(array, sortFunc){
              var tmp = [];
              var aSorted=[];
              var oSorted={};

              for (var k in array) {
                if (array.hasOwnProperty(k))
                    tmp.push({key: k, value:  array[k]});
              }

              tmp.sort(function(o1, o2) {
                    return sortFunc(o1.value, o2.value);
              });

              if(Object.prototype.toString.call(array) === '[object Array]'){
                  $.each(tmp, function(index, value){
                      aSorted.push(value.value);
                  });
                  return aSorted;
              }

              if(Object.prototype.toString.call(array) === '[object Object]'){
                  $.each(tmp, function(index, value){
                      oSorted[value.key]=value.value;
                  });
                  return oSorted;
              }
     };

이제 할 수 있습니다

    console.log("ArraySort");
    var arr1 = [4,3,6,1,2,8,5,9,9];
    var arr2 = {'a':4, 'b':3, 'c':6, 'd':1, 'e':2, 'f':8, 'g':5, 'h':9};
    var arr3 = {a: 'green', b: 'brown', c: 'blue', d: 'red'};
    var result1 = ArraySort(arr1, function(a,b){return a-b});
    var result2 = ArraySort(arr2, function(a,b){return a-b});
    var result3 = ArraySort(arr3, function(a,b){return a>b});
    console.log(result1);
    console.log(result2);
    console.log(result3);