Сортування масиву об’єктів за значеннями властивостей


1331

У мене є такі об'єкти за допомогою AJAX і зберігаються в масиві:

var homes = [
    {
        "h_id": "3",
        "city": "Dallas",
        "state": "TX",
        "zip": "75201",
        "price": "162500"
    }, {
        "h_id": "4",
        "city": "Bevery Hills",
        "state": "CA",
        "zip": "90210",
        "price": "319250"
    }, {
        "h_id": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

Як створити функцію для сортування об'єктів за priceвластивістю у порядку зростання чи спадання лише за допомогою JavaScript?


найшвидший спосіб полягає у використанні ізоморфного модуля сортування масиву, який працює в обох веб-переглядачах і на вузлі, підтримуючи будь-який тип введення, обчислювані поля та замовлення на замовлення.
Ллойд

Відповіді:


1674

Сортувати будинки за ціною у порядку зростання:

homes.sort(function(a, b) {
    return parseFloat(a.price) - parseFloat(b.price);
});

Або після версії ES6:

homes.sort((a, b) => parseFloat(a.price) - parseFloat(b.price));

Деякі документи можна знайти тут .


182
Ви можете використовувати string1.localeCompare(string2)для порівняння рядків
bradvido

62
Майте на увазі, що localeCompare()це нечутливий до випадків . Якщо ви хочете з урахуванням регістру, ви можете використовувати (string1 > string2) - (string1 < string2). Булеві значення примушують до цілих 0 і 1 для обчислення різниці.
Дон Кіркбі

2
Дякую за оновлення, @Pointy, я не пам’ятаю, щоб зіткнутися з цією проблемою, але, можливо, поведінка змінилася за останні пару років. Незалежно від localeCompare()документації видно, що ви можете чітко вказати, чи хочете ви чутливості регістру, числового сортування та інших параметрів.
Дон Кіркбі

2
@ sg28 Я думаю, ви неправильно зрозуміли пояснення MDN. Це не говорить про те, що функція сортування не є надійною , вона говорить про те, що вона не є стабільною . Я розумію, чому це може заплутати, але це не твердження, що воно не підходить для використання. У контексті алгоритмів сортування термін стабільний має конкретне значення - що "рівні" елементи в списку сортуються в тому ж порядку, що і у вхідному . Це абсолютно не пов'язане з ідеєю коду, який є нестабільним (тобто ще не готовий до використання).
Стобор

1
Якщо ви хочете сортувати за певними рядковими значеннями, наприклад за містами, ви можете використовувати: this.homes.sort ((поточний, наступний) => {return current.city.localeCompare (next.city)});
Хорхе Валверт

675

Ось більш гнучка версія, яка дозволяє створювати багаторазові функції сортування та сортувати за будь-яким полем.

const sort_by = (field, reverse, primer) => {

  const key = primer ?
    function(x) {
      return primer(x[field])
    } :
    function(x) {
      return x[field]
    };

  reverse = !reverse ? 1 : -1;

  return function(a, b) {
    return a = key(a), b = key(b), reverse * ((a > b) - (b > a));
  }
}


//Now you can sort by any field at will...

const homes=[{h_id:"3",city:"Dallas",state:"TX",zip:"75201",price:"162500"},{h_id:"4",city:"Bevery Hills",state:"CA",zip:"90210",price:"319250"},{h_id:"5",city:"New York",state:"NY",zip:"00010",price:"962500"}];

// Sort by price high to low
console.log(homes.sort(sort_by('price', true, parseInt)));

// Sort by city, case-insensitive, A-Z
console.log(homes.sort(sort_by('city', false, (a) =>  a.toUpperCase()
)));


7
nickb - ви неправильно читаєте код. sort_byзапускається в O (1) і повертає функцію, використовувану вбудованим сортуванням (O (N log N)) для порівняння елементів у списку. Загальна складність - O (n log n) * O (1), яка зводиться до O (n log n), або така ж, як і швидке сортування.
Триптих

1
Одне питання, з яким я маю, це те, що при reverse = false воно буде сортувати числа як 1,2,3,4 ... але рядки як z, y, x ...
Еббі,

4
Невелике покращення:var key = primer ? function (x) { return primer(x[field]); } : function (x) { return x[field]; }
ErikE

6
Хоча це [1,-1][+!!reverse]виглядає круто, це жахливо робити. Якщо користувач не може правильно зателефонувати на ваш метод, покарайте його, не намагайтеся якось зрозуміти його, незалежно від того.
Інго Бюрк

2
Чи не було б краще підготувати вихідні дані, це спричинить послідовний аналіз, коли очевидно, що вихідні дані потребують певного налаштування.
Герріт Брінк

134

Для їх сортування вам потрібно створити функцію порівняння з двома аргументами. Потім викличте функцію сортування за допомогою цієї функції компаратора так:

// a and b are object elements of your array
function mycomparator(a,b) {
  return parseInt(a.price, 10) - parseInt(b.price, 10);
}
homes.sort(mycomparator);

Якщо ви хочете сортувати висхідний, перемикайте вирази на кожній стороні знаку мінус.


3
І ось посилання, яке насправді пояснює тему, а не говорить "це занадто складно, ви все одно не зрозумієте": developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Roland Illig,

51

для сортування рядків у випадку, якщо комусь це потрібно,

const dataArr = {

  "hello": [{
    "id": 114,
    "keyword": "zzzzzz",
    "region": "Sri Lanka",
    "supportGroup": "administrators",
    "category": "Category2"
  }, {
    "id": 115,
    "keyword": "aaaaa",
    "region": "Japan",
    "supportGroup": "developers",
    "category": "Category2"
  }]

};
const sortArray = dataArr['hello'];

console.log(sortArray.sort((a, b) => {
  if (a.region < b.region)
    return -1;
  if (a.region > b.region)
    return 1;
  return 0;
}));


38

Якщо у вас браузер, сумісний з ES6, ви можете використовувати:

Різниця між порядком зростання і спадання - це знак значення, поверненого вашою функцією порівняння:

var ascending = homes.sort((a, b) => Number(a.price) - Number(b.price));
var descending = homes.sort((a, b) => Number(b.price) - Number(a.price));

Ось фрагмент робочого коду:

var homes = [{
  "h_id": "3",
  "city": "Dallas",
  "state": "TX",
  "zip": "75201",
  "price": "162500"
}, {
  "h_id": "4",
  "city": "Bevery Hills",
  "state": "CA",
  "zip": "90210",
  "price": "319250"
}, {
  "h_id": "5",
  "city": "New York",
  "state": "NY",
  "zip": "00010",
  "price": "962500"
}];

homes.sort((a, b) => Number(a.price) - Number(b.price));
console.log("ascending", homes);

homes.sort((a, b) => Number(b.price) - Number(a.price));
console.log("descending", homes);


22

Ви хочете сортувати його в Javascript, правда? Те, що ви хочете, це sort()функція . У цьому випадку вам потрібно написати функцію компаратора і передати її sort(), щоб щось подібне:

function comparator(a, b) {
    return parseInt(a["price"], 10) - parseInt(b["price"], 10);
}

var json = { "homes": [ /* your previous data */ ] };
console.log(json["homes"].sort(comparator));

Ваш компаратор бере один з кожного вкладеного хешу всередині масиву і вирішує, який з них вище, перевіряючи поле "ціна".


21

Я рекомендую GitHub: Array sortBy - найкраща реалізація sortByметоду, який використовує перетворення Шварца

Але зараз ми спробуємо спробувати такий підхід Gist: sortBy-old.js .
Створимо метод для сортування масивів, здатних упорядкувати об’єкти за якоюсь властивістю.

Створення функції сортування

var sortBy = (function () {
  var toString = Object.prototype.toString,
      // default parser function
      parse = function (x) { return x; },
      // gets the item to be sorted
      getItem = function (x) {
        var isObject = x != null && typeof x === "object";
        var isProp = isObject && this.prop in x;
        return this.parser(isProp ? x[this.prop] : x);
      };

  /**
   * Sorts an array of elements.
   *
   * @param  {Array} array: the collection to sort
   * @param  {Object} cfg: the configuration options
   * @property {String}   cfg.prop: property name (if it is an Array of objects)
   * @property {Boolean}  cfg.desc: determines whether the sort is descending
   * @property {Function} cfg.parser: function to parse the items to expected type
   * @return {Array}
   */
  return function sortby (array, cfg) {
    if (!(array instanceof Array && array.length)) return [];
    if (toString.call(cfg) !== "[object Object]") cfg = {};
    if (typeof cfg.parser !== "function") cfg.parser = parse;
    cfg.desc = !!cfg.desc ? -1 : 1;
    return array.sort(function (a, b) {
      a = getItem.call(cfg, a);
      b = getItem.call(cfg, b);
      return cfg.desc * (a < b ? -1 : +(a > b));
    });
  };

}());

Встановлення несортованих даних

var data = [
  {date: "2011-11-14T16:30:43Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:22:59Z", quantity: 2, total: 90,  tip: 0,   type: "Tab"},
  {date: "2011-11-14T16:28:54Z", quantity: 1, total: 300, tip: 200, type: "visa"},
  {date: "2011-11-14T16:53:41Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:48:46Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T17:25:45Z", quantity: 2, total: 200, tip: 0,   type: "cash"},
  {date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"},
  {date: "2011-11-14T16:58:03Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:20:19Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab"},
  {date: "2011-11-14T17:07:21Z", quantity: 2, total: 90,  tip: 0,   type: "tab"},
  {date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0,   type: "Cash"}
];

Використовуючи його

Впорядкувати масив, з допомогою , "date"якString

// sort by @date (ascending)
sortBy(data, { prop: "date" });

// expected: first element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

Якщо ви хочете ігнорувати регістр, встановіть parserзворотний дзвінок:

// sort by @type (ascending) IGNORING case-sensitive
sortBy(data, {
    prop: "type",
    parser: (t) => t.toUpperCase()
});

// expected: first element
// { date: "2011-11-14T16:54:06Z", quantity: 1, total: 100, tip: 0, type: "Cash" }

// expected: last element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa" }

Якщо ви хочете перетворити "date"поле як Dateтип:

// sort by @date (descending) AS Date object
sortBy(data, {
    prop: "date",
    desc: true,
    parser: (d) => new Date(d)
});

// expected: first element
// { date: "2011-11-31T17:29:52Z", quantity: 1, total: 200, tip: 100, type: "Visa"}

// expected: last element
// { date: "2011-11-01T16:17:54Z", quantity: 2, total: 190, tip: 100, type: "tab" }

Тут ви можете грати з кодом: jsbin.com/lesebi

Завдяки @Ozesh за його відгуками, проблема з властивостями з хибними значеннями була виправлена.


Це, здається, розривається, коли поле є нульовим.
ТСНев

Якщо ви сортуєте числа і зустрічаєте "0" між масивом об'єктів, ви можете помітити, що наведений вище код порушується. Ось короткий виправлення для цього: var checkNaN = function (value) { return Number.isNaN(Number(value)) ? 0 : value; } далі: функція return (масив, o) { .... a = _getItem.call (о, а); a = checkNaN (a); b = _getItem.call (o, b); b = checkNaN (b); повернути o.desc * (a <b? -1: + (a> b)); });
Ожеш

18

Використовуйте lodash.sortBy , (вказівки щодо використання commonjs, ви також можете просто поставити скрипт include-tag для cdn у верхній частині вашого html)

var sortBy = require('lodash.sortby');
// or
sortBy = require('lodash').sortBy;

У порядку зменшення

var descendingOrder = sortBy( homes, 'price' ).reverse();

В порядку зростання

var ascendingOrder = sortBy( homes, 'price' );

1
Абоconst sortBy = require('lodash/sortBy'); let calendars = sortBy(calendarListResponse.items, cal => cal.summary);
mpen

не впевнений, що нещодавно змінився loadash, його назвали OrderByimport { orderBy } from 'lodash'; ... ... return orderBy ( rows, 'fieldName' ).reverse();
montelof

8

Це може бути досягнуто шляхом простої лінії valueof () функції сортування. Запустіть фрагмент коду нижче, щоб побачити демонстрацію.

var homes = [
    {
        "h_id": "3",
        "city": "Dallas",
        "state": "TX",
        "zip": "75201",
        "price": "162500"
    }, {
        "h_id": "4",
        "city": "Bevery Hills",
        "state": "CA",
        "zip": "90210",
        "price": "319250"
    }, {
        "h_id": "5",
        "city": "New York",
        "state": "NY",
        "zip": "00010",
        "price": "962500"
    }
];

console.log("To sort descending/highest first, use operator '<'");

homes.sort(function(a,b) { return a.price.valueOf() < b.price.valueOf();});

console.log(homes);

console.log("To sort ascending/lowest first, use operator '>'");

homes.sort(function(a,b) { return a.price.valueOf() > b.price.valueOf();});

console.log(homes);


8

Я трохи запізнююсь на вечірку, але нижче моя логіка сортування.

function getSortedData(data, prop, isAsc) {
    return data.sort((a, b) => {
        return (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1)
    });
}

6

Хоча мені відомо, що ОП хотіла сортувати масив чисел, це питання було позначене як відповідь на подібні запитання щодо рядків. На цей факт, наведені вище відповіді не враховують сортування масиву тексту там, де важливий об'єм. Більшість відповідей приймають рядкові значення та перетворюють їх у великі / малі регістри, а потім сортують так чи інакше. Вимоги, яких я дотримуюся, прості:

  • Сортування за алфавітом AZ
  • Великі величини одного і того ж слова повинні бути перед малими значеннями
  • Значення однієї літери (A / a, B / b) повинні бути згруповані разом

Я очікую, [ A, a, B, b, C, c ]але відповіді вище повертаються A, B, C, a, b, c. Я фактично почухав голову на цьому довше, ніж хотів (саме тому я публікую це з надією, що це допоможе принаймні одній іншій людині). Хоча двоє користувачів згадують цю localeCompareфункцію в коментарях до поміченої відповіді, я не бачив її, поки не натрапив на функцію під час пошуку. Прочитавши документацію String.prototype.localeCompare (), я зміг придумати це:

var values = [ "Delta", "charlie", "delta", "Charlie", "Bravo", "alpha", "Alpha", "bravo" ];
var sorted = values.sort((a, b) => a.localeCompare(b, undefined, { caseFirst: "upper" }));
// Result: [ "Alpha", "alpha", "Bravo", "bravo", "Charlie", "charlie", "Delta", "delta" ]

Це говорить про функцію сортування великих значень перед малими значеннями. Другий параметр localeCompareфункції - визначити локаль, але якщо ви залишите його так, як undefinedвін автоматично з'ясовує локаль для вас.

Це працює так само і для сортування масиву об’єктів:

var values = [
    { id: 6, title: "Delta" },
    { id: 2, title: "charlie" },
    { id: 3, title: "delta" },
    { id: 1, title: "Charlie" },
    { id: 8, title: "Bravo" },
    { id: 5, title: "alpha" },
    { id: 4, title: "Alpha" },
    { id: 7, title: "bravo" }
];
var sorted = values
    .sort((a, b) => a.title.localeCompare(b.title, undefined, { caseFirst: "upper" }));

5

Ви можете використовувати sortметод JavaScript з функцією зворотного дзвінка:

function compareASC(homeA, homeB)
{
    return parseFloat(homeA.price) - parseFloat(homeB.price);
}

function compareDESC(homeA, homeB)
{
    return parseFloat(homeB.price) - parseFloat(homeA.price);
}

// Sort ASC
homes.sort(compareASC);

// Sort DESC
homes.sort(compareDESC);

4

Ось кульмінація всіх відповідей вище.

Перевірка скрипки: http://jsfiddle.net/bobberino/4qqk3/

var sortOn = function (arr, prop, reverse, numeric) {

    // Ensure there's a property
    if (!prop || !arr) {
        return arr
    }

    // Set up sort function
    var sort_by = function (field, rev, primer) {

        // Return the required a,b function
        return function (a, b) {

            // Reset a, b to the field
            a = primer(a[field]), b = primer(b[field]);

            // Do actual sorting, reverse as needed
            return ((a < b) ? -1 : ((a > b) ? 1 : 0)) * (rev ? -1 : 1);
        }

    }

    // Distinguish between numeric and string to prevent 100's from coming before smaller
    // e.g.
    // 1
    // 20
    // 3
    // 4000
    // 50

    if (numeric) {

        // Do sort "in place" with sort_by function
        arr.sort(sort_by(prop, reverse, function (a) {

            // - Force value to a string.
            // - Replace any non numeric characters.
            // - Parse as float to allow 0.02 values.
            return parseFloat(String(a).replace(/[^0-9.-]+/g, ''));

        }));
    } else {

        // Do sort "in place" with sort_by function
        arr.sort(sort_by(prop, reverse, function (a) {

            // - Force value to string.
            return String(a).toUpperCase();

        }));
    }


}

чи можете ви пояснити, яке значення має * (rev? -1: 1);
TechTurtle

Це для того, щоб змінити порядок (висхідний чи спадаючий) частина обороту просто перевертає нормальні результати, коли аргумент rev є істинним. Інакше він просто кратний на 1, що нічого не робить, коли встановлено, він помножить результат на -1, тим самим перевернувши результат.
боб

3

Я також працював з деяким рейтингом і сортування декількох полів:

arr = [
    {type:'C', note:834},
    {type:'D', note:732},
    {type:'D', note:008},
    {type:'F', note:474},
    {type:'P', note:283},
    {type:'P', note:165},
    {type:'X', note:173},
    {type:'Z', note:239},
];

arr.sort(function(a,b){        
    var _a = ((a.type==='C')?'0':(a.type==='P')?'1':'2');
    _a += (a.type.localeCompare(b.type)===-1)?'0':'1';
    _a += (a.note>b.note)?'1':'0';
    var _b = ((b.type==='C')?'0':(b.type==='P')?'1':'2');
    _b += (b.type.localeCompare(a.type)===-1)?'0':'1';
    _b += (b.note>a.note)?'1':'0';
    return parseInt(_a) - parseInt(_b);
});

Результат

[
    {"type":"C","note":834},
    {"type":"P","note":165},
    {"type":"P","note":283},
    {"type":"D","note":8},
    {"type":"D","note":732},
    {"type":"F","note":474},
    {"type":"X","note":173},
    {"type":"Z","note":239}
]

3

Незважаючи на те, що це трохи надлишковий вміст для сортування одного масиву, ця функція прототипу дозволяє сортувати масиви Javascript за будь-яким ключем у порядку зростання чи спадання, включаючи вкладені ключі , за допомогою dotсинтаксису.

(function(){
    var keyPaths = [];

    var saveKeyPath = function(path) {
        keyPaths.push({
            sign: (path[0] === '+' || path[0] === '-')? parseInt(path.shift()+1) : 1,
            path: path
        });
    };

    var valueOf = function(object, path) {
        var ptr = object;
        for (var i=0,l=path.length; i<l; i++) ptr = ptr[path[i]];
        return ptr;
    };

    var comparer = function(a, b) {
        for (var i = 0, l = keyPaths.length; i < l; i++) {
            aVal = valueOf(a, keyPaths[i].path);
            bVal = valueOf(b, keyPaths[i].path);
            if (aVal > bVal) return keyPaths[i].sign;
            if (aVal < bVal) return -keyPaths[i].sign;
        }
        return 0;
    };

    Array.prototype.sortBy = function() {
        keyPaths = [];
        for (var i=0,l=arguments.length; i<l; i++) {
            switch (typeof(arguments[i])) {
                case "object": saveKeyPath(arguments[i]); break;
                case "string": saveKeyPath(arguments[i].match(/[+-]|[^.]+/g)); break;
            }
        }
        return this.sort(comparer);
    };    
})();

Використання:

var data = [
    { name: { first: 'Josh', last: 'Jones' }, age: 30 },
    { name: { first: 'Carlos', last: 'Jacques' }, age: 19 },
    { name: { first: 'Carlos', last: 'Dante' }, age: 23 },
    { name: { first: 'Tim', last: 'Marley' }, age: 9 },
    { name: { first: 'Courtney', last: 'Smith' }, age: 27 },
    { name: { first: 'Bob', last: 'Smith' }, age: 30 }
]

data.sortBy('age'); // "Tim Marley(9)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Bob Smith(30)"

Сортування за вкладеними властивостями за допомогою крапки-синтаксису або синтаксису масиву:

data.sortBy('name.first'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy(['name', 'first']); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

Сортування за кількома клавішами:

data.sortBy('name.first', 'age'); // "Bob Smith(30)", "Carlos Jacques(19)", "Carlos Dante(23)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"
data.sortBy('name.first', '-age'); // "Bob Smith(30)", "Carlos Dante(23)", "Carlos Jacques(19)", "Courtney Smith(27)", "Josh Jones(30)", "Tim Marley(9)"

Ви можете роздрібнити репо: https://github.com/eneko/Array.sortBy


Мені дуже подобається ця відповідь через sortByстислий синтаксис. Простий у використанні - навіть із вкладеними полями - зберігаючи велику читабельність коду. Дякую!
Манфред Урбан

3

З ECMAScript 6 відповідь StoBor можна зробити ще більш стислим:

homes.sort((a, b) => a.price - b.price)

3

Порядок зменшення ціни:

homes.sort((x,y) => {return y.price - x.price})

Порядок зростання за ціною:

homes.sort((x,y) => {return x.price - y.price})

2

Для сортування масиву необхідно визначити функцію порівняння. Ця функція завжди відрізнятиметься від бажаного шаблону або порядку сортування (тобто висхідного чи низхідного).

Дозвольте створити деякі функції, які сортують масив у зростаючій чи низхідній формі, який містить об'єкт, рядок або числові значення.

function sorterAscending(a,b) {
    return a-b;
}

function sorterDescending(a,b) {
    return b-a;
}

function sorterPriceAsc(a,b) {
    return parseInt(a['price']) - parseInt(b['price']);
}

function sorterPriceDes(a,b) {
    return parseInt(b['price']) - parseInt(b['price']);
}

Сортування чисел (в алфавітному порядку та за зростанням):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();

Сортувати номери (в алфавітному порядку та за убуванням):

var fruits = ["Banana", "Orange", "Apple", "Mango"];
fruits.sort();
fruits.reverse();

Сортування чисел (чисельно та за зростанням):

var points = [40,100,1,5,25,10];
points.sort(sorterAscending());

Сортування чисел (чисельних та низхідних):

var points = [40,100,1,5,25,10];
points.sort(sorterDescending());

Як описано вище, використовуйте метод sorterPriceAsc та sorterPriceDes зі своїм масивом із потрібним ключем.

homes.sort(sorterPriceAsc()) or homes.sort(sorterPriceDes())


2

Ось трохи модифікована версія елегантної реалізації з книги "JavaScript: хороші частини".

Примітка : Ця версія byİŞ стабільною . Він зберігає порядок першого сортування під час виконання наступного ланцюгового сортування.

Я додав isAscendingдо нього параметр. Також перетворили його вES6 стандарти та "новіші" хороші частини, як рекомендував автор.

Ви можете сортувати як висхідні, так і низхідні та ланцюгові сортування за кількома властивостями.

const by = function (name, minor, isAscending=true) {
    const reverseMutliplier = isAscending ? 1 : -1;
    return function (o, p) {
        let a, b;
        let result;
        if (o && p && typeof o === "object" && typeof p === "object") {
            a = o[name];
            b = p[name];
            if (a === b) {
                return typeof minor === 'function' ? minor(o, p) : 0;
            }
            if (typeof a === typeof b) {
                result = a < b ? -1 : 1;
            } else {
                result = typeof a < typeof b ? -1 : 1;
            }
            return result * reverseMutliplier;
        } else {
            throw {
                name: "Error",
                message: "Expected an object when sorting by " + name
            };
        }
    };
};

let s = [
    {first: 'Joe',   last: 'Besser'},
    {first: 'Moe',   last: 'Howard'},
    {first: 'Joe',   last: 'DeRita'},
    {first: 'Shemp', last: 'Howard'},
    {first: 'Larry', last: 'Fine'},
    {first: 'Curly', last: 'Howard'}
];

// Sort by: first ascending, last ascending
s.sort(by("first", by("last")));    
console.log("Sort by: first ascending, last ascending: ", s);     // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"Besser"},     <======
//     {"first":"Joe","last":"DeRita"},     <======
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]

// Sort by: first ascending, last descending
s.sort(by("first", by("last", 0, false)));  
console.log("sort by: first ascending, last descending: ", s);    // "[
//     {"first":"Curly","last":"Howard"},
//     {"first":"Joe","last":"DeRita"},     <========
//     {"first":"Joe","last":"Besser"},     <========
//     {"first":"Larry","last":"Fine"},
//     {"first":"Moe","last":"Howard"},
//     {"first":"Shemp","last":"Howard"}
// ]


ми могли б сортувати {"first":"Curly","last":"Howard", "property" : {"id" : "1"}}тип масиву за id?
Вішал Кумар Саху

так, функцію слід трохи змінити, щоб прийняти новий параметр, скажімо, nestedName. Потім ви телефонуєте byз name = "властивість", nestedName = "id"
mythicalcoder

2

Лише для звичайного масиву значень елементів:

function sortArrayOfElements(arrayToSort) {
    function compareElements(a, b) {
        if (a < b)
            return -1;
        if (a > b)
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareElements);
}

e.g. 1:
var array1 = [1,2,545,676,64,2,24]
output : [1, 2, 2, 24, 64, 545, 676]

var array2 = ["v","a",545,676,64,2,"24"]
output: ["a", "v", 2, "24", 64, 545, 676]

Для масиву об'єктів:

function sortArrayOfObjects(arrayToSort, key) {
    function compareObjects(a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    }

    return arrayToSort.sort(compareObjects);
}

e.g. 1: var array1= [{"name": "User4", "value": 4},{"name": "User3", "value": 3},{"name": "User2", "value": 2}]

output : [{"name": "User2", "value": 2},{"name": "User3", "value": 3},{"name": "User4", "value": 4}]

2

Створіть функцію та сортуйте на основі вхідних даних за допомогою наведеного нижче коду

var homes = [{

    "h_id": "3",
    "city": "Dallas",
    "state": "TX",
    "zip": "75201",
    "price": "162500"

 }, {

    "h_id": "4",
    "city": "Bevery Hills",
    "state": "CA",
    "zip": "90210",
    "price": "319250"

 }, {

    "h_id": "5",
    "city": "New York",
    "state": "NY",
    "zip": "00010",
    "price": "962500"

 }];

 function sortList(list,order){
     if(order=="ASC"){
        return list.sort((a,b)=>{
            return parseFloat(a.price) - parseFloat(b.price);
        })
     }
     else{
        return list.sort((a,b)=>{
            return parseFloat(b.price) - parseFloat(a.price);
        });
     }
 }

 sortList(homes,'DESC');
 console.log(homes);

2

Для порівняння рядків можна використовувати string1.localeCompare (string2)

this.myArray.sort((a,b) => { 
    return a.stringProp.localeCompare(b.stringProp);
});

Зверніть увагу , що localCompareв разі в чутливої


1

Для сортування по полі об'єкта з декількома масивами. Введіть ім’я поля в arrpropмасив, як ["a","b","c"] потім, передайте у другому параметрі arrsourceфактичне джерело, яке ми хочемо сортувати.

function SortArrayobject(arrprop,arrsource){
arrprop.forEach(function(i){
arrsource.sort(function(a,b){
return ((a[i] < b[i]) ? -1 : ((a[i] > b[i]) ? 1 : 0));
});
});
return arrsource;
}

1

Вам знадобиться дві функції

function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
  return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

Потім ви можете застосувати це до будь-якого об'єкта властивості:

 data.sort((a, b) => desc(parseFloat(a.price), parseFloat(b.price)));

let data = [
    {label: "one", value:10},
    {label: "two", value:5},
    {label: "three", value:1},
];

// sort functions
function desc(a, b) {
 return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
}

function asc(a, b) {
 return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}

// DESC
data.sort((a, b) => desc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>DESCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);

// ASC
data.sort((a, b) => asc(a.value, b.value));

document.body.insertAdjacentHTML(
 'beforeend', 
 '<strong>ASCending sorted</strong><pre>' + JSON.stringify(data) +'</pre>'
);


0

Нещодавно я написав універсальну функцію для управління цим для вас, якщо ви хочете ним скористатися.

/**
 * Sorts an object into an order
 *
 * @require jQuery
 *
 * @param object Our JSON object to sort
 * @param type Only alphabetical at the moment
 * @param identifier The array or object key to sort by
 * @param order Ascending or Descending
 *
 * @returns Array
 */
function sortItems(object, type, identifier, order){

    var returnedArray = [];
    var emptiesArray = []; // An array for all of our empty cans

    // Convert the given object to an array
    $.each(object, function(key, object){

        // Store all of our empty cans in their own array
        // Store all other objects in our returned array
        object[identifier] == null ? emptiesArray.push(object) : returnedArray.push(object);

    });

    // Sort the array based on the type given
    switch(type){

        case 'alphabetical':

            returnedArray.sort(function(a, b){

                return(a[identifier] == b[identifier]) ? 0 : (

                    // Sort ascending or descending based on order given
                    order == 'asc' ? a[identifier] > b[identifier] : a[identifier] < b[identifier]

                ) ? 1 : -1;

            });

            break;

        default:

    }

    // Return our sorted array along with the empties at the bottom depending on sort order
    return order == 'asc' ? returnedArray.concat(emptiesArray) : emptiesArray.concat(returnedArray);

}

0
homes.sort(function(a, b){
  var nameA=a.prices.toLowerCase(), nameB=b.prices.toLowerCase()
  if (nameA < nameB) //sort string ascending
    return -1 
  if (nameA > nameB)
    return 1
  return 0 //default return value (no sorting)
})

0

Привіт, прочитавши цю статтю, я зробив sortComparator для моїх потреб, з функціоналом для порівняння декількох атрибутів json, і я хочу поділитися цим з вами.

Це рішення порівнює лише рядки у порядку зростання, але рішення можна легко розширити на кожен атрибут, який підтримується: зворотне впорядкування, інші типи даних, щоб використовувати локаль, кастинг тощо

var homes = [{

    "h_id": "3",
    "city": "Dallas",
    "state": "TX",
    "zip": "75201",
    "price": "162500"

}, {

    "h_id": "4",
    "city": "Bevery Hills",
    "state": "CA",
    "zip": "90210",
    "price": "319250"

}, {

    "h_id": "5",
    "city": "New York",
    "state": "NY",
    "zip": "00010",
    "price": "962500"

}];

// comp = array of attributes to sort
// comp = ['attr1', 'attr2', 'attr3', ...]
function sortComparator(a, b, comp) {
    // Compare the values of the first attribute
    if (a[comp[0]] === b[comp[0]]) {
        // if EQ proceed with the next attributes
        if (comp.length > 1) {
            return sortComparator(a, b, comp.slice(1));
        } else {
            // if no more attributes then return EQ
            return 0;
        }
    } else {
        // return less or great
        return (a[comp[0]] < b[comp[0]] ? -1 : 1)
    }
}

// Sort array homes
homes.sort(function(a, b) {
    return sortComparator(a, b, ['state', 'city', 'zip']);
});

// display the array
homes.forEach(function(home) {
    console.log(home.h_id, home.city, home.state, home.zip, home.price);
});

і результат є

$ node sort
4 Bevery Hills CA 90210 319250
5 New York NY 00010 962500
3 Dallas TX 75201 162500

та інший сорт

homes.sort(function(a, b) {
    return sortComparator(a, b, ['city', 'zip']);
});

з результатом

$ node sort
4 Bevery Hills CA 90210 319250
3 Dallas TX 75201 162500
5 New York NY 00010 962500

0

Простий код:

    var homes = [
        {
            "h_id": "3",
            "city": "Dallas",
            "state": "TX",
            "zip": "75201",
            "price": "162500"
        }, {
            "h_id": "4",
            "city": "Bevery Hills",
            "state": "CA",
            "zip": "90210",
            "price": "319250"
        }, {
            "h_id": "5",
            "city": "New York",
            "state": "NY",
            "zip": "00010",
            "price": "962500"
        }
    ];

    let sortByPrice = homes.sort(function (a, b) 
    {
      return parseFloat(b.price) - parseFloat(a.price);
    });

    for (var i=0; i<sortByPrice.length; i++)
    {
      document.write(sortByPrice[i].h_id+' '+sortByPrice[i].city+' '
       +sortByPrice[i].state+' '
       +sortByPrice[i].zip+' '+sortByPrice[i].price);
      document.write("<br>");
    }


0
 function compareValues(key, order = 'asc') {
  return function innerSort(a, b) {
    if (!a.hasOwnProperty(key) || !b.hasOwnProperty(key)) {
      // property doesn't exist on either object
      return 0;
    }

    const varA = (typeof a[key] === 'string')
      ? a[key].toUpperCase() : a[key];
    const varB = (typeof b[key] === 'string')
      ? b[key].toUpperCase() : b[key];

    let comparison = 0;
    if (varA > varB) {
      comparison = 1;
    } else if (varA < varB) {
      comparison = -1;
    }
    return (
      (order === 'desc') ? (comparison * -1) : comparison
    );
  };
}

http://yazilimsozluk.com/sort-array-in-javascript-by-asc-or-desc

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.