Попытка отсортировать пользовательский объект JavaScript - PullRequest
3 голосов
/ 30 июля 2010

Я не слишком хорош в JS, но до сих пор выжил. Я создаю сложный JS-объект и хочу его отсортировать. Структура объекта выглядит следующим образом:

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

Я создаю уникальный атрибут, который сообщает мне 3 вещи, произвольно разделенные двоеточием:
(ID продукта) :( Итератор QTY продукта) :( Имя атрибута)
Итератор QTY продукта просто означает, если у меня есть 3 одинаковых продукта, о каком из 3 я говорю с точки зрения атрибута. Каждый атрибут имеет значение.

ПРОБЛЕМА Как вы увидите из распечатки, организации нет. Я хотел бы отсортировать эти результаты сначала по (Product ID), затем (QTY Iterator), а затем по алфавиту (Name).

Вот распечатка объекта с использованием следующего метода для его распечатки, а затем результаты.

ИСПОЛЬЗОВАНИЕ КОДА ДЛЯ РЕЗУЛЬТАТОВ ПЕЧАТИ

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

РЕЗУЛЬТАТЫ

«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

Ответы [ 5 ]

4 голосов
/ 30 июля 2010

Хорошо, из комментариев ниже, я получил более четкое представление о том, что это за объект.

Предполагается, что объект выглядит так:

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

Это не может быть отсортировано, так как это не массив. Но вы можете разобрать его для печати. ​​

В простом старом 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]]);
}
3 голосов
/ 30 июля 2010

Прежде всего, действительно сложно понять структуру объекта.Это то, на что это похоже?

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

Похоже, вы хотите, чтобы он сортировался в

[
  {  "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 },
]

Следующее решение работает, если я понял структуру вашего объекта.Как сказал 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];
      };
    }
  }
});

Однако объект действительно не имеет смысла.Я призываю вас переосмыслить его структуру.Даже если я не до конца понял ваш объект (вы должны были указать фактический json для этого объекта), этот пример говорит вам все, что вам нужно знать о сортировке в js.

3 голосов
/ 30 июля 2010

Вы должны иметь возможность сортировать массив объектов на основе атрибутов объекта, написав специальную функцию сортировки следующим образом:

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

Где ProductID - это атрибут вашего объекта. Вы бы назвали это так:

  myArray.sort(customSortByPID);

Это должно как минимум помочь вам начать писать собственные функции сортировки. Помните, что JavaScript не является строго типизированным, что может привести к неожиданному поведению сортировки (обработка int как строки).

** ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ ** Я не проверял ничего из вышеперечисленного, это просто у меня на макушке.

1 голос
/ 03 июля 2013

Что-то вроде этого работает хорошо, и вы можете легко определить функцию для ее обтекания и сортировать объекты 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' } );
1 голос
/ 30 июля 2010

Во-первых, вам не хватает смысла создания объектов, если вы помещаете несколько значений в строку, разделенную разделителем.Вместо этого структура должна быть:

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

Создание функции для создания объекта из закодированной строки тривиально.Разбейте строку на ':' и запишите каждую часть отдельно.

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

Пример использования:

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

возвращает объект:

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

Общий способсортировка объекта по нескольким полям приведена в этом ответе .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...