用值的对象对对象集合进行排序

时间:2018-08-27 20:48:32

标签: javascript sorting object

我正在尝试按一个值对一组对象进行排序,这些对象本身具有用于其值的对象。

为清楚起见,我想按每个对象的值对象中的名称字符串对结果进行排序。

这与其他问题(我相信...包括上面列出为“可能重复的...”的问题)不同,因为我正在对包含其他值对象的值进行排序,而不仅仅是从单个值开始。

我有一个看起来像的对象

foo = {
  9876: {name: 'Banana', id:'875465'},
  4536: {name: 'Pear', id:'285610'},
  8732: {name: 'Apple', id:'013452'}
}

我想按名称值按字母顺序对该对象进行排序。

如果我尝试按Object.values进行排序,则返回的结果将按名称值正确进行排序,但返回结果如下:

[
  0: {name: 'Apple', id:'013452'}
  1: {name: 'Banana', id:'875465'}
  2: {name: 'Pear', id:'285610'}
]

但是,我需要保留我的相同对象集合,只是排序正确。没有数组,没有数字键...我只想要上面的foo,但按名称排序:

foo = {
  8732: {name: 'Apple', id:'013452'},
  9876: {name: 'Banana', id:'875465'},
  4536: {name: 'Pear', id:'285610'}
}

我该如何使用Javascript?


为完整起见,这是我目前正在尝试使用的排序方法:

const sortStuff = (key) => {
  return (a, b) => {
    if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
      return 0;
    }

    const avalue = (typeof a[key] === 'string') ?
      a[key].toLowerCase() : a[key];
    const bvalue = (typeof b[key] === 'string') ?
      b[key].toLowerCase() : b[key];

    let comp = 0;
    if (avalue > bvalue) {
      comp = 1;
    }
    if (avalue < bvalue) {
      comp = -1;
    }

    return comp
  }
}

我像这样食用

Object.values(foo).sort(sortStuff('name'))

1 个答案:

答案 0 :(得分:0)

首先,您需要创建一个自定义排序功能。在此步骤之后,然后遍历对象并将每个元素与所有其他元素进行比较。如果发现一个元素不正确,请交换该元素。最好举个例子。

// Current data set
foo = {
  9876: {name: 'Banana', id:'875465'},
  4536: {name: 'Pear', id:'285610'},
  8732: {name: 'Apple', id:'013452'}
}

// Custom compare function
function objectSorter(a, b){
    if(!a.hasOwnProperty("name") || !b.hasOwnProperty("name")) {
       return 0;
    }
    var x = a.name.toLowerCase();
    var y = b.name.toLowerCase();
    if (x < y) {return -1;}
    if (x > y) {return 1;}
    return 0;
};

// Compare each element
for(var item in foo)
  {
    // with all the other elements in the object
    for(var next in foo)
      {
        // if the outer item is less than the inner item
        // then swap places.
        if(objectSorter(foo[item], foo[next]) == -1)
        {
          var temp = foo[item];
          foo[item] = foo[next];
          foo[next] = temp;
        }
      }
  }

// Print out the newly ordered data set
console.log(foo);

//我的输出

{…}
​    4536: Object { name: "Apple", id: "013452" }
    8732: Object { name: "Banana", id: "875465" }
    9876: Object { name: "Pear", id: "285610" }
    <prototype>: Object { … }

但是您很可能不想让您的代码起作用的排序答案。通过使用您的代码,我发现它可以将数据从对象中剥离,然后将它们放入数组中。这不是你想要的。这就是为什么您会使用我的最初答案。但这就是我在您的代码中发现的。

foo = {
  9876: {name: 'Banana', id:'875465'},
  4536: {name: 'Pear', id:'285610'},
  8732: {name: 'Apple', id:'013452'},
  3536: {name: 'Peach', id:'385610'},
  5732: {name: 'Grape', id:'513452'}
};

var sortStuff = (key) => {
  return (a, b) => {
    if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
      return 0;
    }
    var avalue = (typeof a[key] === 'string') ? a[key].toLowerCase()  : a[key];
    var bvalue = (typeof b[key] === 'string') ? b[key].toLowerCase()  : b[key];
    var comp = 0;
    if (avalue > bvalue) {
      comp = 1;
    }
    else if (avalue < bvalue) {
      comp = - 1;
    }
    return comp;
  }
};


var resultFoo = Object.values(foo).sort(sortStuff('name'));

console.log(resultFoo, foo);

//注意,将打印resultFoo并同时打印foo。

(5) […]
​0: Object { name: "Apple", id: "013452" }
​1: Object { name: "Banana", id: "875465" }
​2: Object { name: "Grape", id: "513452" }
​3: Object { name: "Peach", id: "385610" }
​4: Object { name: "Pear", id: "285610" }
​length: 5
​
{…}
​3536: Object { name: "Peach", id: "385610" }
​4536: Object { name: "Pear", id: "285610" }
​5732: Object { name: "Grape", id: "513452" }
​8732: Object { name: "Apple", id: "013452" }
​9876: Object { name: "Banana", id: "875465" }
​

创建Object.values并不是为了返回对象,而是创建它是为了返回数组。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values

这样,您会发现使用Object.values并不是丢失数据的选择。