Сортировать коллекцию объектов с объектами по значениям - PullRequest
0 голосов
/ 27 августа 2018

Я пытаюсь отсортировать по одному значению коллекцию объектов, которые сами имеют объекты для своих значений.

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

Это отличается от других вопросов (я полагаю ... включая тот, который указан выше как "Возможный дубликат ...") тем, что я сортирую по значению, которое состоит из объекта других значений, а не просто от одного значения.

У меня есть объект, который выглядит следующим образом:

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

Я хочу отсортировать этот объект в алфавитном порядке по значению имени.

Если я попытаюсь отсортировать по Object.values, возвращаемые результаты будут правильно отсортированы по значению имени, но результат thr будет выглядеть так:

[
  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 голосов
/ 28 августа 2018

Первое, что вам нужно сделать, это создать собственную функцию сортировки. После этого шага переберите объект и сравните каждый элемент со всеми другими элементами. Если один из элементов окажется не на своем месте, поменяйте местами элемент. Лучше всего с примером.

// 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 ​​не подходит для потери данных.

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