按值对对象属性进行排序

如果我有一个JavaScript对象,例如:

var list = {
  "you": 100, 
  "me": 75, 
  "foo": 116, 
  "bar": 15
};

有没有一种方法可以基于值对属性进行排序?这样我最终

list = {
  "bar": 15, 
  "me": 75, 
  "you": 100, 
  "foo": 116
};
GONear2020/03/11 15:19:26

Using query-js you can do it like this

list.keys().select(function(k){
    return {
        key: k,
        value : list[k]
    }
}).orderBy(function(e){ return e.value;});

You can find an introductory article on query-js here

米亚ItachiL2020/03/11 15:19:26

Try this. Even your object is not having the property based on which you are trying to sort also will get handled.

Just call it by sending property with object.

var sortObjectByProperty = function(property,object){

    console.time("Sorting");
    var  sortedList      = [];
         emptyProperty   = [];
         tempObject      = [];
         nullProperty    = [];
    $.each(object,function(index,entry){
        if(entry.hasOwnProperty(property)){
            var propertyValue = entry[property];
            if(propertyValue!="" && propertyValue!=null){
              sortedList.push({key:propertyValue.toLowerCase().trim(),value:entry});  
            }else{
                emptyProperty.push(entry);
           }
        }else{
            nullProperty.push(entry);
        }
    });

      sortedList.sort(function(a,b){
           return a.key < b.key ? -1 : 1;
         //return a.key < b.key?-1:1;   // Asc 
         //return a.key < b.key?1:-1;  // Desc
      });


    $.each(sortedList,function(key,entry){
        tempObject[tempObject.length] = entry.value;
     });

    if(emptyProperty.length>0){
        tempObject.concat(emptyProperty);
    }
    if(nullProperty.length>0){
        tempObject.concat(nullProperty);
    }
    console.timeEnd("Sorting");
    return tempObject;
}
Davaid达蒙2020/03/11 15:19:26

Another way to solve this:-

var res = [{"s1":5},{"s2":3},{"s3":8}].sort(function(obj1,obj2){ 
 var prop1;
 var prop2;
 for(prop in obj1) {
  prop1=prop;
 }
 for(prop in obj2) {
  prop2=prop;
 }
 //the above two for loops will iterate only once because we use it to find the key
 return obj1[prop1]-obj2[prop2];
});

//res will have the result array

西里GO2020/03/11 15:19:26

Thank you and continue answer @Nosredna

Now that we understand object need to be converted to array then sort the array. this is useful for sorting array (or converted object to array) by string:

Object {6: Object, 7: Object, 8: Object, 9: Object, 10: Object, 11: Object, 12: Object}
   6: Object
   id: "6"
   name: "PhD"
   obe_service_type_id: "2"
   __proto__: Object
   7: Object
   id: "7"
   name: "BVC (BPTC)"
   obe_service_type_id: "2"
   __proto__: Object


    //Sort options
    var sortable = [];
    for (var vehicle in options)
    sortable.push([vehicle, options[vehicle]]);
    sortable.sort(function(a, b) {
        return a[1].name < b[1].name ? -1 : 1;
    });


    //sortable => prints  
[Array[2], Array[2], Array[2], Array[2], Array[2], Array[2], Array[2]]
    0: Array[2]
    0: "11"
    1: Object
        id: "11"
        name: "AS/A2"
        obe_service_type_id: "2"
        __proto__: Object
        length: 2
        __proto__: Array[0]
    1: Array[2]
    0: "7"
    1: Object
        id: "7"
        name: "BVC (BPTC)"
        obe_service_type_id: "2"
        __proto__: Object
        length: 2
小小前端2020/03/11 15:19:25
    var list = {
    "you": 100,
    "me": 75,
    "foo": 116,
    "bar": 15
};
var tmpList = {};
while (Object.keys(list).length) {
    var key = Object.keys(list).reduce((a, b) => list[a] > list[b] ? a : b);
    tmpList[key] = list[key];
    delete list[key];
}
list = tmpList;
console.log(list); // { foo: 116, you: 100, me: 75, bar: 15 }
Gil前端2020/03/11 15:19:24

many similar and useful functions: https://github.com/shimondoodkin/groupbyfunctions/

function sortobj(obj)
{
    var keys=Object.keys(obj);
    var kva= keys.map(function(k,i)
    {
        return [k,obj[k]];
    });
    kva.sort(function(a,b){
        if(a[1]>b[1]) return -1;if(a[1]<b[1]) return 1;
        return 0
    });
    var o={}
    kva.forEach(function(a){ o[a[0]]=a[1]})
    return o;
}

function sortobjkey(obj,key)
{
    var keys=Object.keys(obj);
    var kva= keys.map(function(k,i)
    {
        return [k,obj[k]];
    });
    kva.sort(function(a,b){
        k=key;      if(a[1][k]>b[1][k]) return -1;if(a[1][k]<b[1][k]) return 1;
        return 0
    });
    var o={}
    kva.forEach(function(a){ o[a[0]]=a[1]})
    return o;
}
番长Green2020/03/11 15:19:24

Object sorted by value (DESC)

function sortObject(list) {
  var sortable = [];
  for (var key in list) {
    sortable.push([key, list[key]]);
  }

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

  var orderedList = {};
  for (var i = 0; i < sortable.length; i++) {
    orderedList[sortable[i][0]] = sortable[i][1];
  }

  return orderedList;
}
米亚小小神乐2020/03/11 15:19:24
a = { b: 1, p: 8, c: 2, g: 1 }
Object.keys(a)
  .sort((c,b) => {
    return a[b]-a[c]
  })
  .reduce((acc, cur) => {
    let o = {}
    o[cur] = a[cur]
    acc.push(o)
    return acc
   } , [])

output = [ { p: 8 }, { c: 2 }, { b: 1 }, { g: 1 } ]

猿阿飞Tom2020/03/11 15:19:24

This could be a simple way to handle it as a real ordered object. Not sure how slow it is. also might be better with a while loop.

Object.sortByKeys = function(myObj){
  var keys = Object.keys(myObj)
  keys.sort()
  var sortedObject = Object()
  for(i in keys){
    key = keys[i]
    sortedObject[key]=myObj[key]
   }

  return sortedObject

}

And then I found this invert function from: http://nelsonwells.net/2011/10/swap-object-key-and-values-in-javascript/

Object.invert = function (obj) {

  var new_obj = {};

  for (var prop in obj) {
    if(obj.hasOwnProperty(prop)) {
      new_obj[obj[prop]] = prop;
    }
  }

  return new_obj;
};

So

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var invertedList = Object.invert(list)
var invertedOrderedList = Object.sortByKeys(invertedList)
var orderedList = Object.invert(invertedOrderedList)
阿飞飞云2020/03/11 15:19:24

Just in case, someone is looking for keeping the object (with keys and values), using the code reference by @Markus R and @James Moran comment, just use:

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
var newO = {};
Object.keys(list).sort(function(a,b){return list[a]-list[b]})
                 .map(key => newO[key] = list[key]);
console.log(newO);  // {bar: 15, me: 75, you: 100, foo: 116}
小胖泡芙2020/03/11 15:19:24

Very short and simple!

var sortedList = {};
Object.keys(list).sort((a,b) => list[a]-list[b]).forEach((key) => {
    sortedList[key] = list[key]; });
StafanNearPro2020/03/11 15:19:24

I am following the solution given by slebetman (go read it for all the details), but adjusted, since your object is non-nested.

// First create the array of keys/values so that we can sort it:
var sort_array = [];
for (var key in list) {
    sort_array.push({key:key,value:list[key]});
}

// Now sort it:
sort_array.sort(function(x,y){return x.value - y.value});

// Now process that object with it:
for (var i=0;i<sort_array.length;i++) {
    var item = list[sort_array[i].key];

    // now do stuff with each item
}
小卤蛋Tom2020/03/11 15:19:24

Underscore.js or Lodash.js for advanced array or object sorts

 var data={
        "models": {

            "LTI": [
                "TX"
            ],
            "Carado": [
                "A",
                "T",
                "A(пасс)",
                "A(груз)",
                "T(пасс)",
                "T(груз)",
                "A",
                "T"
            ],
            "SPARK": [
                "SP110C 2",
                "sp150r 18"
            ],
            "Autobianchi": [
                "A112"
            ]
        }
    };

    var arr=[],
        obj={};
    for(var i in data.models){
      arr.push([i, _.sortBy(data.models[i],function (el){return el;})]);
    }
    arr=_.sortBy(arr,function (el){
      return el[0];
    });
    _.map(arr,function (el){return obj[el[0]]=el[1];});
     console.log(obj);

demo

村村路易2020/03/11 15:19:24
var list = {
    "you": 100, 
    "me": 75, 
    "foo": 116, 
    "bar": 15
};

function sortAssocObject(list) {
    var sortable = [];
    for (var key in list) {
        sortable.push([key, list[key]]);
    }
    // [["you",100],["me",75],["foo",116],["bar",15]]

    sortable.sort(function(a, b) {
        return (a[1] < b[1] ? -1 : (a[1] > b[1] ? 1 : 0));
    });
    // [["bar",15],["me",75],["you",100],["foo",116]]

    var orderedList = {};
    for (var idx in sortable) {
        orderedList[sortable[idx][0]] = sortable[idx][1];
    }

    return orderedList;
}

sortAssocObject(list);

// {bar: 15, me: 75, you: 100, foo: 116}
LEYJim2020/03/11 15:19:24

OK, as you may know, javascript has sort() function, to sort arrays, but nothing for object...

So in that case, we need to somehow get array of the keys and sort them, thats the reason the apis gives you objects in an array most of the time, because Array has more native functions to play with them than object literal, anyway, the quick solotion is using Object.key which return an array of the object keys, I create the ES6 function below which does the job for you, it uses native sort() and reduce() functions in javascript:

function sortObject(obj) {
  return Object.keys(obj)
    .sort().reduce((a, v) => {
    a[v] = obj[v];
    return a; }, {});
}

And now you can use it like this:

let myObject = {a: 1, c: 3, e: 5, b: 2, d: 4};
let sortedMyObject = sortObject(myObject);

Check the sortedMyObject and you can see the result sorted by keys like this:

{a: 1, b: 2, c: 3, d: 4, e: 5}

同样,通过这种方式,主对象也不会被触摸,实际上我们得到了一个新对象。

我还创建了下面的图像,以使功能步骤更清晰,以防万一您需要对其进行一些更改以使其按自己的方式工作:

按属性值对JavaScript对象进行排序

凯Gil2020/03/11 15:19:23

ECMAScript 2017引入了Object.values / Object.entries顾名思义,前者将对象的所有值聚合到一个数组中,后者将整个对象聚合到一个数组中[key, value]Python的等价于dict.values()dict.items()

The features make it pretty easier to sort any hash into an ordered object. As of now, only a small portion of JavaScript platforms support them, but you can try it on Firefox 47+.

let obj = {"you": 100, "me": 75, "foo": 116, "bar": 15};

let entries = Object.entries(obj);
// [["you",100],["me",75],["foo",116],["bar",15]]

let sorted = entries.sort((a, b) => a[1] - b[1]);
// [["bar",15],["me",75],["you",100],["foo",116]]
凯梅小胖2020/03/11 15:19:23

@marcusR的答案的“箭头”版本以供参考

var myObj = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(myObj).sort((a,b) => myObj[a]-myObj[b])
alert(keysSorted);     // bar,me,you,foo

更新:20174月 -这将返回myObj上面定义的排序对象。

Object
 .keys(myObj)
 .sort((a, b) => myObj[a]-myObj[b])
 .reduce((_sortedObj, key) => ({
   ..._sortedObj, 
   [key]: myObj[key]
 }), {})

在这里尝试!

更新:201810月 -Object.entries版本

Object
 .entries(myObj)
 .sort()
 .reduce((_sortedObj, [k,v]) => ({
   ..._sortedObj, 
   [k]: v
 }), {})

在这里尝试!

Green前端2020/03/11 15:19:23

根据定义,JavaScript对象是无序的(请参阅ECMAScript语言规范第8.6节)。语言规范甚至不能保证,如果您连续两次遍历对象的属性,那么第二次它们将以相同的顺序出现。

如果需要订购商品,请使用数组和Array.prototype.sort方法。

西里凯2020/03/11 15:19:23

我们不想复制整个数据结构,也不想在需要关联数组的地方使用数组。

这是与bonna相同的另一种方式:

var list = {"you": 100, "me": 75, "foo": 116, "bar": 15};
keysSorted = Object.keys(list).sort(function(a,b){return list[a]-list[b]})
console.log(keysSorted);     // bar,me,you,foo

2020/03/11 15:19:23

将它们移动到一个数组,对该数组进行排序,然后将其用于您的目的。这是一个解决方案:

var maxSpeed = {
    car: 300, 
    bike: 60, 
    motorbike: 200, 
    airplane: 1000,
    helicopter: 400, 
    rocket: 8 * 60 * 60
};
var sortable = [];
for (var vehicle in maxSpeed) {
    sortable.push([vehicle, maxSpeed[vehicle]]);
}

sortable.sort(function(a, b) {
    return a[1] - b[1];
});

//[["bike", 60], ["motorbike", 200], ["car", 300],
//["helicopter", 400], ["airplane", 1000], ["rocket", 28800]]

拥有数组后,您可以按自己喜欢的顺序从数组中重建对象,从而完全实现了您打算要做的事情。在我所知道的所有浏览器中都可以使用,但这取决于实现的怪癖,并且可能随时中断。您永远不应假设JavaScript对象中元素的顺序。

var objSorted = {}
sortable.forEach(function(item){
    objSorted[item[0]]=item[1]
})