Pertanyaan Bagaimana mengurutkan array asosiatif berdasarkan nilainya dalam Javascript?


Saya memiliki array asosiatif:

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

Apa cara paling elegan untuk mengurutkan (descending) berdasarkan nilainya di mana hasilnya akan berupa array dengan indeks masing-masing dalam urutan ini:

sub2, sub3, sub1, sub4, sub0?

75
2018-03-04 22:17


asal


Jawaban:


Javascript tidak memiliki "associative arrays" seperti yang Anda pikirkan. Sebaliknya, Anda hanya memiliki kemampuan untuk mengatur properti objek menggunakan sintaks seperti array (seperti dalam contoh Anda), ditambah kemampuan untuk iterate atas properti objek.

Dengan hasil ini adalah bahwa tidak ada jaminan untuk memesan di mana Anda iterate atas properti, sehingga tidak ada yang seperti semacam bagi mereka. Sebagai gantinya, Anda harus mengonversi properti objek Anda menjadi larik "asli" (yang menjamin pesanan). Berikut adalah cuplikan kode untuk mengonversi objek menjadi larik dua tupel (dua elemen array), menyortirnya seperti yang Anda gambarkan, lalu mengulanginya:

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
}

Anda mungkin merasa lebih alami untuk membungkus ini dalam fungsi yang mengambil callback:

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>


108
2018-03-04 22:31



Alih-alih mengoreksi Anda di semantik dari 'array asosiatif', saya pikir ini adalah apa yang Anda inginkan:

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

Anda membuang objek (seperti milik Anda) dan mendapatkan array kunci - eh properti - kembali, diurutkan turun dengan nilai (numerik) dari, eh, nilai dari, eh, objek.

Ini hanya berfungsi jika nilai Anda numerik. Tweek si kecil function(a,b) di sana untuk mengubah mekanisme penyortiran untuk bekerja naik, atau bekerja untuk string nilai-nilai (misalnya). Waktu sebagai latihan untuk pembaca.

EDIT: orang terus menaikkan jawaban ini, tapi itu benar-benar sudah tua. Silahkan   mempertimbangkan kembali mengapa Anda tidak hanya menggunakan Object.keys () sekarang.


69
2017-08-04 20:25



Diskusi lanjutan & solusi lain yang dibahas di Bagaimana mengurutkan array (asosiatif) berdasarkan nilai? dengan solusi terbaik (untuk kasus saya) adalah oleh saml (dikutip di bawah).

Array hanya dapat memiliki indeks numerik. Anda harus menulis ulang ini sebagai Objek, atau Array Objek.

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});

Jika Anda suka status.push metode, Anda dapat mengatasinya dengan:

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

15
2017-10-08 23:27



Sebenarnya tidak ada yang namanya "associative array" di JavaScript. Apa yang Anda dapatkan di sana hanyalah objek lama. Mereka bekerja seperti array asosiatif, tentu saja, dan kunci tersedia tetapi tidak ada semantik di sekitar susunan kunci.

Anda bisa mengubah objek Anda menjadi array objek (pasangan kunci / nilai) dan mengurutkan itu:

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;
}

Maka Anda akan menyebutnya dengan fungsi komparator.


5
2018-03-04 22:30



Berikut ini adalah variasi jawaban ben kosong, jika Anda tidak suka tupel.

Ini menghemat beberapa karakter.

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.
}

4
2018-05-02 18:21



Tidak diperlukan komplikasi yang tidak perlu ...

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;
}

4
2018-01-10 05:07



saya menggunakan $ .seach jquery tetapi Anda dapat membuatnya dengan for loop, perbaikan adalah ini:

        //.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;
              }               
     };

Jadi sekarang Anda bisa melakukannya

    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);

1
2017-07-19 13:22