简体   繁体   English

array.sort在对象数组上不起作用

[英]array.sort not working on array of objects

I got the following object array: 我得到以下对象数组:

var arr = [{
    2: {
        1: { name: "test" },
        2: { name: "apple" }
    },
    3: {
        1: { name: "banana" },
        2: { name: "pear" }
    }
}];

Just some sample data. 只是一些样本数据。 Now, I got 3 textareas: 现在,我得到了3个文本区域:

<textarea id="first"></textarea>
<textarea id="second"></textarea>
<textarea id="third"></textarea>

And I have the following custom-made function: 我具有以下定制功能:

function sort(alt)
{
    arr.sort(function (a,b) 
    {
        console.log(a);
        if (a[2].name < a[2].name)
            return (alt) ? 1 : -1;
        if (a[2].name > a[2].name)
            return (alt) ? -1 : 1;
        return 0;
    });
}

It should sort the array of objects by name, ascending or descending according to parameter. 它应按名称对对象数组进行排序,并根据参数升序或降序。 Now, I got 2 problems. 现在,我遇到了2个问题。 This way I append all the values to the textareas: 这样,我将所有值附加到文本区域:

for (var key in arr[0])
{
    var obj = arr[0][key];
    $(ID).append(obj[2].name + '\n');
}

The first time, that code will be executed without running sort . 第一次,该代码将在不运行sort情况下执行。 The second time, sort will be executed with false as parameter, than that code will be executed. 第二次,将使用false作为参数执行sort然后执行该代码。 The third time sort will be executed with true as parameter, than that code will be executed. 第三次sort将以true作为参数执行,然后执行该代码。 However, the output of all textboxes is exactly the same. 但是,所有文本框的输出完全相同。

This is a link to the jsfiddle: 这是jsfiddle的链接:

http://jsfiddle.net/JoshB1997/gow4vzsc/ http://jsfiddle.net/JoshB1997/gow4vzsc/

Also, the console.log(a) doesn't get printed in the console. 另外, console.log(a)不会在控制台中打印。

So variable arr is an array but as far as I can see it contains only one object. 因此变量arr是一个数组,但据我所知,它仅包含一个对象。

You're trying to sort directly onto the array, since it only has one object it will simply never sort because there is nothing to sort. 您正在尝试直接在数组上进行排序,因为它只有一个对象,因为根本没有排序对象,所以它将永远不会进行排序。

You'll want to access arr[0] which is the object containing the actual objects you want to sort however the Object prototype doesn't contain any of the array functions so you cannot call sort on it even tho technically an Array is an Object an Array inherits from Object and not the other way around so the methods from Object are available to Array but not the other way around. 你要访问arr[0]这是一个包含要排序的实际对象,不过该对象Object原型不包含任何的阵列功能,这样你就不能调用sort甚至寿技术上的Array是一个Object ArrayObject继承而来,而不是从Object继承,因此Object的方法对Array可用,但不是相反。

Also, you're trying to compare the same a[2].name with itself so it'll always be false since it's equal, not > or < . 另外,您尝试将相同的a[2].name与自身进行比较,因此它始终为false,因为它相等,而不是><

In your case I extract all the name properties from every nested object you have like this ( considering the usage of the original arr ): 在您的情况下,我从每个嵌套对象中提取所有name属性,如下所示( 考虑原始arr的用法 ):

var compare = [];
var alt = false;
for (k in arr[0]) {
    if (arr[0].hasOwnProperty(k)) {
        for (l in arr[0][k])
            if (arr[0][k].hasOwnProperty(l))
                compare.push(arr[0][k][l].name);

compare.sort(function(a, b) {
    if (a == b)
        return 0;
    else if (a < b)
        return alt ? 1 : -1
    else
        return alt ? -1 : 1
});

Now you can use the compare array to output the sorted names correctly. 现在,您可以使用compare数组正确输出排序后的名称。 Also - your construction seems overly complex? 另外-您的构造似乎过于复杂? It has objects and within them are nested objects but you're only sorting and displaying names, is there any reason this structure has to be maintained? 它具有对象,并且在它们内部是嵌套对象,但是您只是在排序和显示名称,是否有任何理由必须维护此结构?

If not I would highly recommend you simplify this to just be an array of names, the loop I made above is far from beautiful and I'd rather have you not use it since it assumes that the outmost object is an object filled with other objects that all have the name property. 如果不是,我强烈建议您将其简化为只是一个名称数组,我在上面所做的循环远非美丽,我希望您不要使用它,因为它假定最外面的对象是一个充满其他对象的对象都具有name属性。 This code could still break without an extra arr[0][k][l].hasOwnProperty('name') . 如果没有额外的arr[0][k][l].hasOwnProperty('name')此代码仍可能会中断。

Either way, the compare array simply contains all the names and it easily sortable with the default sort if you don't make things to complex for yourself. 无论哪种方式, compare数组仅包含所有名称,并且如果您不自己做复杂的事情,则可以使用默认sort轻松地对其进行排序。

I suggest you to use http://underscorejs.org/ that contains quite really useful function to transform from object to arrays. 我建议您使用http://underscorejs.org/ ,它包含了非常有用的功能,可以将对象从数组转换为数组。

For example in this case you can use something like http://underscorejs.org/#values 例如,在这种情况下,您可以使用类似http://underscorejs.org/#values的名称

let values = _.values(arr[0]);

Now values is an array that contains your two object (2,3) in the form 现在值是一个数组,其中包含两个对象(2,3),形式为

values = [
    {
      1: {
          name: "test"
      },
      2: {
          name: "apple"
      }
    },
    {
      1: {
          name: "banana"
      },
      2: {
          name: "pear"
      }
    }
]

and here you can call your sort function 在这里您可以调用您的排序功能

There is my demo on your code with underscore.js http://jsfiddle.net/gow4vzsc/3/ 我的演示在您的代码中使用了underscore.js http://jsfiddle.net/gow4vzsc/3/

EDIT: If you cant/wont to include an entire library you can write your code for get the values: 编辑:如果您不能/不想包括整个库,则可以编写代码以获取值:

values = [];
for(key in arr[0]){
    values.push(arr[0][key]);   
}

Here a demo without underscore.js http://jsfiddle.net/3L7ttu2r/1/ 这是一个没有underscore.js的演示http://jsfiddle.net/3L7ttu2r/1/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM