尝试对自定义 JavaScript 对象进行排序

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3368036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 00:59:38  来源:igfitidea点击:

Trying to sort a custom JavaScript object

javascriptarrayssortingobject

提问by Mike B.

I'm not too good at JS, but have survived thus far. I'm creating a sort-of complex JS object and wanting to sort it. The object's structure looks like this:

我不太擅长 JS,但到目前为止还幸存下来。我正在创建一个复杂的 JS 对象并想要对其进行排序。对象的结构如下所示:

cart.attributes = [
  {
    Attribute,
    Value
  }
  ...
];

I'm creating a unique attribute that tells me 3 things separated arbitrarily by a colon:
(Product ID):(Product QTY Iterator):(Attribute's Name)
The product QTY iterator just means, if I have 3 of the same product, which of the 3 am I talking about in terms of the attribute. Each attribute has then a value.

我正在创建一个独特的属性,它告诉我用冒号任意分隔的 3 个东西
:(产品 ID):(产品数量迭代器):(属性名称)
产品数量迭代器只是意味着,如果我有 3 个相同的产品,在我谈论的 3 种属性中。每个属性都有一个值。

THE PROBLEMAs you'll see from the print-out, there's no organization. I'd like to sort these results first by the (Product ID), then the (QTY Iterator), then alphabetically by (Name).

问题正如您从打印输出中看到的那样,没有组织。我想首先按(产品 ID)对这些结果进行排序,然后是(数量迭代器),然后按字母顺序(名称)。

Here's a print out of the object using the following method to print it out, and then the results.

下面是一个打印出来的对象,用下面的方法把它打印出来,然后是结果。

CODE USING TO PRINT RESULTS

用于打印结果的代码

$.each(cart.attributes, function(attr, value) {
  console.log("Attr: "+attr);
  console.log("Value: "+value);
});

RESULTS

结果

?Attr? 46913872:2:Size
?Value? 10
?Attr? 46913872:2:Hollow-to-Hem
?Value? 57"
?Attr? 46913872:1:Hips
?Value? 34"
?Attr? 46913872:2:Bust
?Value? 34"
?Attr? 46913872:2:Dress Color (hex)
?Value? #FFFFFF
?Attr? 46913872:2:Rush Cut
?Value? Super Rush Cut - 6 weeks
?Attr? 46913872:1:Extra Length
?Value? 5"
?Attr? 46913872:2:Hips
?Value? 34"
?Attr? 46913872:1:Waist
?Value? 29"
?Attr? 46913872:2:Waist
?Value? 23"
?Attr? 46913872:2:Dress Color (name)
?Value? White
?Attr? 46913872:1:Rush Cut
?Value? Super Rush Cut - 6 weeks
?Attr? 46913872:1:Sash Color (name)
?Value? Lipstick
?Attr? 46913872:2:Sash Color (hex)
?Value? #000000
?Attr? 46913872:1:Size
?Value? 14
?Attr? 46913872:1:Hollow-to-Hem
?Value? 58"
?Attr? 46913872:1:Bust
?Value? 35"
?Attr? 46913872:1:Sash Color (hex)
?Value? #B6064C
?Attr? 46913872:1:Dress Color (hex)
?Value? #F9C8D0
?Attr? 46913872:1:Dress Color (name)
?Value? Tea Rose
?Attr? 46913872:2:Extra Length
?Value? 5"
?Attr? 46913872:2:Sash Color (name)
?Value? Black

回答by slebetman

Ok from the comments below I got a clearer picture of what the object is.

好的,从下面的评论中,我更清楚地了解了对象是什么。

Assuming the object looks like this:

假设对象如下所示:

cart.attributes = {
    '46913872:2:Size' : 10,
    '46913872:2:Hollow-to-Hem' : 57
    // ...
}

It can't be sorted since it's not an Array. But you can sort it out for printing.

它不能排序,因为它不是数组。但是你可以整理出来打印。

In plain old javascript you can do:

在普通的旧 javascript 中,您可以执行以下操作:

// First get all keys:
var keys = [];
for (var n in cart.attributes) {
    if (cart.attributes.hasOwnProperty(n)) {
        keys.push(n);
    }
}

// now sort the keys:
keys.sort(function(a,b){
    attr_a = a.split(':');
    attr_b = b.split(':');

    // sort by product ID:
    if (parseInt(attr_a[0],10) < parseInt(attr_b[0],10)) return -1;
    if (parseInt(attr_a[0],10) > parseInt(attr_b[0],10)) return 1;
    // sort by quantity:
    if (parseInt(attr_a[1],10) < parseInt(attr_b[1],10)) return -1;
    if (parseInt(attr_a[1],10) > parseInt(attr_b[1],10)) return 1;
    // finally sort by name:
    if (attr_a[2] < attr_b[2]) return -1;
    if (attr_a[2] > attr_b[2]) return 1;
    return 0;
})

// now print out the object in key-sorted-order:
for (var i=0; i<keys.length; i++) {
    console.log("Attr: "+keys[i]);
    console.log("Value: "+cart.attributes[keys[i]]);
}

回答by ThatSteveGuy

You should be able to sort an array of objects, based on the object attributes, by writing a custom sort function like so:

通过编写自定义排序函数,您应该能够根据对象属性对对象数组进行排序,如下所示:

function customSortByPID(a,b) {
  if (a.ProductID > b.ProductID)
  {
      return 1;
  }
  else if (a.ProductID < b.ProductID)
  {
      return -1;
  }
  return 0;
}

Where ProductID is an attribute of your object. You would call it like this:

其中 ProductID 是对象的属性。你会这样称呼它:

  myArray.sort(customSortByPID);

That should at least get you started on how to write custom sort functions. Be aware that JavaScript is not strongly typed, which couldlead to unexpected sorting behavior (treating an int like a string).

这至少应该让您开始了解如何编写自定义排序函数。请注意,JavaScript 不是强类型的,这可能会导致意外的排序行为(将 int 视为字符串)。

** DISCLAIMER ** I didn't test any of the above, it's just off the top of my head.

** 免责声明 ** 我没有测试以上任何一项,它只是我的头顶。

回答by Juan Mendes

First of all, it's really hard to understand the structure of the object. Is this what it looks like?

首先,真的很难理解对象的结构。这是它的样子吗?

[
  {  "46913872:2:Size" : 10 },
  {  "46913872:2:Hollow-to-Hem": 57},
  {  "46913872:1:Hips" : "34"}, ...
]

It looks like you want it to sort to

看起来你希望它排序

[
  {  "46913872:1:Hips" : "34"}, // all ids are the same here, but this index is 1
  {  "46913872:2:Hollow-to-Hem": 57}, // index is 2 but Hollow comes before Size
  {  "46913872:2:Size" : 10 },
]

The following solution works if I understood your object structure. Like ThatSteveGuy said, you can pass a comparator to your sort method. Since the object is so complicated, this is what you would do

如果我了解您的对象结构,则以下解决方案有效。就像 ThatSteveGuy 所说的,您可以将比较器传递给您的排序方法。由于对象是如此复杂,这就是你要做的

attributes.sort(function(a, b){
  // Make sense of your objects a and b. See the inner function defined below
  var newA = improveObject(a);
  var newB = improveObject(b);

  if (newA.id > newB.id) { return 1; }
  if (newA.id < newB.id) { return -1; }
  // id is the same, check index
  if (newA.index > newB.index) { return 1; }
  if (newA.index < newB.index) { return -1; }
  // index is the same, check name
  if (newA.name > newB.name) { return 1; }
  if (newA.name < newB.name) { return -1; }
  // it's the same thing 
  return 0;

  // Turns {  "46913872:2:Size" : 10 }
  // into {id: 46913872, index: 2, name: "Size", value: 10}
  function improveObject(obj) {
    for (var key in obj) {
      var pieces = key.split(":");
      return {
        id: parseInt(pieces[0]),
        index: parseInt(pieces[1]),
        name: pieces[2],
        value: obj[key];
      };
    }
  }
});

However, the object really doesn't make sense. I would urge you to re-think its structure. Even if I didn't fully understand your object (you should have listed the actual json for the object), the example tells you all you need to know about sorting in js.

但是,对象确实没有意义。我会敦促你重新考虑它的结构。即使我没有完全理解你的对象(你应该已经列出了对象的实际 json),这个例子告诉你所有你需要知道的关于在 js 中排序的知识。

回答by Anurag

You are missing the point of creating objects in the first place if you are putting multiple values in a string separated by a delimiter. The structure should instead be,

如果您将多个值放在由分隔符分隔的字符串中,那么您首先就错过了创建对象的重点。结构应该是,

cart.attributes = [
    {
        attributes: {
            id: "46913872",
            quantityIterator: 2,
            name: "Dress Color"
        },
        value: "57",
    },
    // repeat for each product
];

Making a function to create an object from the encoded string is trivial. Split the string by ':' and record each part separately.

制作一个函数来从编码的字符串创建一个对象是微不足道的。用':'分割字符串并分别记录每个部分。

function makeProduct(key, val) {
    var parts = key.split(':');

    var attrs = {};
    attrs.productId = parts[0];
    attrs.quantityIterator = parts[1];
    attrs.name = parts[2];

    return { attributes: attrs, value: val};
}

Example usage:

用法示例:

makeProduct("46913872:2:Bust", 34); 

returns the object:

返回对象:

{
    attributes: {
        name: "Bust",
        productId: "46913872",
        quantityIterator: "2"
    },
    value: 34
}

A generic way to sort an object by multiple fields is listed in this answer.

答案中列出了按多个字段对对象进行排序的通用方法。

回答by Nour Sharabash

Something like this works well, and you can easily define a function to wrap around it and sort jQuery objects given the comparison attribute:

像这样的东西运行良好,您可以轻松定义一个函数来环绕它并根据比较属性对 jQuery 对象进行排序:

    var $jobj = jQuery( '.jcss' ); // your selector here
    var $jarr = [];

    $jobj.each( function () {
        $jarr.push( jQuery( this ) );
    } );

    $jarr.sort( function ( a, b ) {
        var attr = {}; // your comparison attribute here
        attr.a = parseInt( a.data( 'priority' ) || 0 );
        attr.b = parseInt( b.data( 'priority' ) || 0 );
        return attr.a < attr.b ? -1 : attr.a > attr.b ? 1 : 0;
    } );

    $jobj = jQuery( jQuery.map( $jarr, function ( obj, i ) {
        return obj[0];
    } ) );

    // whatever you need to do here
    $jobj.css( { 'text-decoration': 'blink' } );