Как отсортировать список словарей по значениям словаря в Google App Script / Javascript? [Дубликат]

Вот решение:

<?php
// here's the pattern:
$pattern = '/<(\w+)(\s+(\w+)\s*\=\s*(\'|")(.*?)\\4\s*)*\s*(\/>|>)/';

// a string to parse:
$string = 'Hello, try clicking <a href="#paragraph">here</a>
    <br/>and check out.<hr />
    <h2>title</h2>
    <a name ="paragraph" rel= "I\'m an anchor"></a>
    Fine, <span title=\'highlight the "punch"\'>thanks<span>.
    <div class = "clear"></div>
    <br>';

// let's get the occurrences:
preg_match_all($pattern, $string, $matches, PREG_PATTERN_ORDER);

// print the result:
print_r($matches[0]);
?>

Чтобы проверить его глубоко, я ввел в теги автоматического закрытия строки, например:

  1. & lt; hr / & gt;
  2. & lt; br / & gt;
  3. & lt; br & gt;

Я также вводил теги с:

  1. один атрибут
  2. содержит более одного атрибута
  3. , значение которого привязано либо в одинарные кавычки, либо в двойные кавычки
  4. атрибуты, содержащие одинарные кавычки, когда разделитель является двойным цитата и наоборот
  5. «нечеткие» атрибуты с пробелом перед символом «=» после него и до и после него.

Если вы найдете что-то, что не работает в доказательстве концепции выше, я доступен для анализа кода, чтобы улучшить свои навыки.

& lt; EDIT & gt; Я забыл, что вопрос от пользователя заключался в том, чтобы избежать разбора самозакрывающихся тегов. В этом случае шаблон проще, превратившись в это:

$pattern = '/<(\w+)(\s+(\w+)\s*\=\s*(\'|")(.*?)\\4\s*)*\s*>/';

Пользователь @ridgerunner заметил, что шаблон не позволяет без кавычек атрибутов или атрибутов без значения. В этом случае тонкая настройка приводит к следующему шаблону:

$pattern = '/<(\w+)(\s+(\w+)(\s*\=\s*(\'|"|)(.*?)\\5\s*)?)*\s*>/';

& lt; / EDIT & gt;

Понимание шаблона

Если кто-то заинтересован в обучении подробнее о шаблоне, я предоставляю некоторую строку:

  1. первое подвыражение (\ w +) соответствует имени тега
  2. , второе подвыражение содержит шаблон атрибут. Он состоит из: одного или нескольких пробелов \ s + имя атрибута (\ w +) ноль или более пробелов \ s * (возможно или нет, оставляя здесь пробелы) символ "=" снова, ноль или более пробелов разделитель значения атрибута, одинарная или двойная кавычка («|»). В шаблоне одиночная кавычка экранируется, потому что она совпадает с разделителем строки PHP. Это подвыражение захватывается скобками, поэтому на него можно ссылаться снова для синтаксического анализа закрытия атрибута, поэтому очень важно значение атрибута, сопоставляемое почти : (. *?); в этом конкретном синтаксисе, используя жадное соответствие ( вопросительный знак после звездочки), механизм RegExp позволяет использовать оператор «look-ahead», который соответствует чему-либо, но что следует за этим подвыражением, здесь весело: элемент \ 4 является оператором обратной ссылки, который ссылается на подзадачу, выражение, определенное ранее в шаблоне, в данном случае я имею в виду четвертое подвыражение, которое является первым a ttribute delimiter обнаружен ноль или более пробелов \ s * конец суб-выражения атрибута заканчивается здесь, с указанием нуля или более возможных вхождений, заданных звездочкой.
  3. Затем, поскольку тег может заканчиваться пробелом перед «& gt;», символ, ноль или более пробелов сопоставляются с подшаблоном \ s *.
  4. Тег, который должен соответствовать, может заканчиваться простым «& gt;» символ или возможное закрытие XHTML, которое использует перед ним косую черту: (/> |>). Слэш, конечно, сбежал, поскольку он совпадает с разделителем регулярных выражений.

Небольшой совет: чтобы лучше проанализировать этот код, необходимо посмотреть на исходный код, сгенерированный с тех пор, как я не представил любые специальные символы HTML.

1043
задан 18 revs, 9 users 22%TomHankers 24 January 2017 в 23:05
поделиться

25 ответов

Сортировка домов по цене в порядке возрастания:

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

Или после версии ES6:

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

Некоторую документацию можно найти здесь здесь .

1334
ответ дан Alexander Shtang 15 August 2018 в 23:44
поделиться
  • 1
    Вы можете использовать string1.localeCompare(string2) для сравнения строк – bradvido 27 May 2014 в 14:51
  • 2
    Имейте в виду, что localeCompare() является регистром нечувствительным . Если вам нужен регистр с регистром, вы можете использовать (string1 > string2) - (string1 < string2). Булевские значения принудительно приводят к целому числу 0 и 1 для вычисления разности. – Don Kirkby 1 May 2015 в 21:58
  • 3
    Есть ли способ передать аргумент функции сравнения? Думали ли вы сделать эту функцию многократного использования, к которой я мог бы передать ключ для сортировки объекта? – jlbriggs 13 July 2015 в 15:00
  • 4
  • 5
    Спасибо за обновление, @Pointy, я не помню, как работает эта проблема, но, возможно, поведение изменилось за последние пару лет. Независимо от того, что localeCompare() документация показывает, что вы можете явно указать, хотите ли вы чувствительность к регистру, числовую сортировку и другие параметры. – Don Kirkby 28 August 2017 в 16:11

Я рекомендую 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 по его обратной связи проблема, связанная с свойствами с значениями falsy , была исправлена.

20
ответ дан 15 revs, 2 users 98% 15 August 2018 в 23:44
поделиться
  • 1
    Я добавил новую и более мощную реализацию, позволяющую несколько сортировать, например. field1 ASC, после field2 DESC, после field3 DESC. Новый sortBy метод представляет собой реализацию преобразования Шварца , и вы можете найти его здесь: gist: sortBy.js – jherax 11 April 2016 в 04:07
  • 2
    Кажется, что это ломается, когда поле равно нулю. – TSNev 25 August 2016 в 13:51
  • 3
    @TSNev не могли бы вы привести пример (jsfiddle, plunkr и т. Д.)? Я попытался воспроизвести его без успеха, значения null были упорядочены в конце массива. – jherax 25 August 2016 в 17:11
  • 4
    В случае, если вы сортируете числа, и вы сталкиваетесь с «0» между массивом объектов, вы можете заметить, что приведенный выше код разбивается. Вот краткое исправление для этого: var checkNaN = function (value) { return Number.isNaN(Number(value)) ? 0 : value; }, за которым следуют: return function (array, o) {.... a = _getItem.call (o, a); a = checkNaN (a); b = _getItem.call (o, b); b = checkNaN (b); return o.desc * (a & lt; b? -1: + (a & gt; b)); }); – Ozesh 20 October 2016 в 04:29
  • 5
    Спасибо за ваши отзывы @Ozesh, версия sortBy выше устарела :) Я написал новую и более мощную реализацию для сортировки массивов. Проверьте этот параметр: sortBy – jherax 20 October 2016 в 04:43

Я также работал с каким-то рейтингом и несколькими полями sort:

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
ответ дан 2 revs 15 August 2018 в 23:44
поделиться

Если у вас есть 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);

28
ответ дан 3 revs 15 August 2018 в 23:44
поделиться
  • 1
    Он возвращает тот же массив как для нисходящей, так и восходящей функции. Я чувствую там жучок. – Hynek 28 May 2018 в 20:40
  • 2
    Спасибо за ваш комментарий, @Hynek. Я изменил образец, чтобы показать, что функция sort() изменяет исходный массив. – Stephen Quan 29 May 2018 в 00:40

Это могло быть достигнуто с помощью простой функции сортировки value (). Выполните фрагмент кода ниже, чтобы увидеть демонстрацию.

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

7
ответ дан Ajay Singh 15 August 2018 в 23:44
поделиться

Вот кульминация всех ответов выше.

Проверка правильности: 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();

        }));
    }


}
3
ответ дан bob 15 August 2018 в 23:44
поделиться
  • 1
    можете ли вы объяснить, в чем смысл наличия * (rev? -1: 1); – TechTurtle 28 September 2017 в 16:59
  • 2
    Это для того, чтобы обратить вспять порядок (восходящий и нисходящий), оборотная часть просто переворачивает нормальные результаты, когда аргумент rev является истинным. В противном случае он будет просто несколько на 1, который ничего не делает, когда будет установлен, он умножит результат на -1, тем самым инвертируя результат. – bob 29 September 2017 в 18:16

Недавно я написал универсальную функцию для управления этим для вас, если вы хотите его использовать.

/**
 * 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
ответ дан Brad Bird 15 August 2018 в 23:44
поделиться

С ответом ECMAScript 6 StoBor можно сделать еще более кратким:

homes.sort((a, b) => a.price - b.price)
1
ответ дан CracyD 15 August 2018 в 23:44
поделиться

В то время как это немного переполняет только сортировку одного массива, эта функция прототипа позволяет сортировать массивы 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

2
ответ дан Eneko Alonso 15 August 2018 в 23:44
поделиться

Используйте lodash.sortBy , (инструкции с использованием commonjs, вы также можете просто поместить [tag] тег 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' );
15
ответ дан Evan Carroll 15 August 2018 в 23:44
поделиться
  • 1
    Или const sortBy = require('lodash/sortBy'); let calendars = sortBy(calendarListResponse.items, cal => cal.summary); – mpen 17 October 2016 в 01:13
  • 2
    не уверен, что недавно измененный lodash изменил его имя OrderBy import { orderBy } from 'lodash'; ... ... return orderBy ( rows, 'fieldName' ).reverse(); – montelof 8 December 2016 в 22:56

Привет, прочитав эту статью, я сделал 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

и другой sort

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
ответ дан George Vrynios 15 August 2018 в 23:44
поделиться

для сортировки строк в случае, если кому-то это нужно,

var dataArr = {  

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

};
var sortArray = dataArr['hello'];
sortArray.sort(function(a,b) {
    if ( a.region < b.region )
        return -1;
    if ( a.region > b.region )
        return 1;
    return 0;
} );
34
ответ дан Ishan Liyanage 15 August 2018 в 23:44
поделиться
  • 1
    не знаю, почему мой ответ обозначен как сообщение в сообществе wiki :-( – Ishan Liyanage 29 April 2015 в 11:29
  • 2
    Я предполагаю, что это было потому, что сам вопрос был отмечен как вики сообщества. – trichoplax 11 June 2015 в 13:30
  • 3
    По-видимому, you сделал это сообщение CW: «Post Made Community Wiki by Ishan Liyanage». – Léo Lam 14 July 2015 в 01:56
  • 4
    Я сам задал этот вопрос. Благодарю вас от прошлого! :-) – Ishan Liyanage 19 January 2016 в 04:18

Вы можете использовать метод JavaScript sort с функцией обратного вызова:

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);
3
ответ дан John G 15 August 2018 в 23:44
поделиться

Для сортировки массива вы должны определить функцию компаратора.

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

]
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())
1
ответ дан Lalit Kumar 15 August 2018 в 23:44
поделиться

Ниже приведена более гибкая версия, которая позволяет создавать функции сортировки повторного использования и сортировать по любому полю.

var sort_by = function(field, reverse, primer){

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

Теперь вы можете сортировать по любому полю по желанию ...

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"

}];

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

// Sort by city, case-insensitive, A-Z
homes.sort(sort_by('city', false, function(a){return a.toUpperCase()}));
624
ответ дан Mariano Desanze 15 August 2018 в 23:44
поделиться
  • 1
    nickb - вы неправильно читаете код. sort_by работает в O (1) и возвращает функцию, используемую встроенной сортировкой (O (N log N)) для сравнения элементов в списке. Общая сложность - O (n log n) * O (1), которая сводится к O (n log n) или такая же, как и быстрая сортировка. – Triptych 31 October 2011 в 09:04
  • 2
    Отличная идея! Несколько вопросов: 1-левая скобка, кажется, не в том месте. 2-Настройка обратного просмотра обратная :) 3-Line break, похоже, вызывает проблемы. В целом, не должен ли быть один лайнер return (A < B ? -1 : (A > B ? 1 : 0)) * [1,-1][+!!reverse];? – Halil Özgür 9 December 2011 в 17:52
  • 3
    Вот рабочий пример этого кода: jsfiddle.net/dFNva/1 – Blake Mills 17 January 2013 в 06:32
  • 4
    Я только что нашел объяснение: + преобразует boolean в число; !! преобразует небулево значение в boolean. ( dreaminginjavascript.wordpress.com/2008/07/04/28 ) Итак, [+!!reverse] предоставляет индекс для массива [-1,1], оценивающий либо [-1,1][0], либо [-1,1][1], который оценивает -1 или 1. Это потрясающе, но сбивает с толку. – gfullam 23 May 2014 в 16:24
  • 5
    Вот скрипка, основанная на скрипте @Blake Mills: jsfiddle.net/gfullam/sq9U7 | Он исправляет ошибку, отмеченную Abby, и реализует "тогда" сортировка, запрошенная AlanJames, используя метод Crockford для передачи в другой сортировке по вызову функции в качестве опции. – gfullam 23 May 2014 в 19:09

Хотя я знаю, что OP хотел сортировать массив чисел, этот вопрос был помечен как ответ на аналогичные вопросы относительно строк. В связи с этим в вышеприведенных ответах не рассматривается сортировка массива текста, где важна обсадка. Большинство ответов принимают строковые значения и преобразуют их в верхний регистр / строчный регистр, а затем сортируют так или иначе. Требования, которые я придерживаюсь, просты:

  • Сортировка по алфавиту 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" }));
0
ответ дан Mitchell Skurnik 15 August 2018 в 23:44
поделиться

Вот немного измененная версия элегантной реализации из книги «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"}
// ]

1
ответ дан mythicalcoder 15 August 2018 в 23:44
поделиться
  • 1
    почему мой ответ wiki сообщества? – mythicalcoder 7 February 2017 в 22:43
  • 2
    мы могли бы отсортировать {"first":"Curly","last":"Howard", "property" : {"id" : "1"}} тип массива по id? – Vishal Kumar Sahu 14 August 2017 в 08:29
  • 3
    да, функция должна быть слегка изменена, чтобы принять новый параметр, скажем, nestedName. Затем вы вызываете by с именем = & quot; property & quot ;, nestedName = & quot; id & quot; – mythicalcoder 15 August 2017 в 21:29

Вам понадобится две функции

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>'
);

1
ответ дан OzzyCzech 15 August 2018 в 23:44
поделиться

Для сортировки по полю нескольких объектов массива. Введите имя своего поля в массив 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;
}
0
ответ дан Pradip Talaviya 15 August 2018 в 23:44
поделиться
2
ответ дан Raghd Hamzeh 15 August 2018 в 23:44
поделиться

Только для нормального массива значений элементов:

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
ответ дан Umesh 15 August 2018 в 23:44
поделиться
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
ответ дан user3346960 15 August 2018 в 23:44
поделиться

Если вы используете Underscore.js , попробуйте sortBy:

// price is of an integer type
_.sortBy(homes, "price"); 

// price is of a string type
_.sortBy(homes, function(home) {return parseInt(home.price);}); 
3
ответ дан Vitalii Fedorenko 15 August 2018 в 23:44
поделиться

Вы хотите отсортировать его в 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));

. Ваш компаратор принимает одну из каждого из вложенных хэшей внутри массива и решает, какой из них выше, проверяя поле «цена».

127
ответ дан Web_Designer 15 August 2018 в 23:44
поделиться
127
ответ дан Web_Designer 5 September 2018 в 23:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: