У меня есть массив объектов JavaScript:

Предостережение для предоставленных хостом объектов

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

Как их отсортировать по значению last_nom Итак, в качестве третьей альтернативы вышеприведенному, использование атрибутов данных для декларативного объявления поведения в разметке. Поведение скрыто от глаз, но сразу видно, что происходит.

ложное имя как для супруга, так и для возраста, Вы можете продолжить. В противном случае у вас есть только одно поле со значением (или с очень ранним браком), и вам нужно создать дополнительную ошибку в вашей sort(a,b), но это только работает строки и числа. Нужно ли добавлять toString() JSON.parse () преобразует любую строку JSON, переданную в функцию, в объект JSON.

Достаточно просто написать собственную функцию сравнения:

function compare( a, b ) {
  if ( a.last_nom < b.last_nom ){
    return -1;
  }
  if ( a.last_nom > b.last_nom ){
    return 1;
  }
  return 0;
}

objs.sort( compare );

Вы должны знать, что функции на самом деле являются объектами в JavaScript {*** } внутренне мы создали объект для указанной выше функции и дали ему имя с именем fn, или ссылка на объект сохраняется в fn. Функции — это объекты в JavaScript ;, экземпляр функции на самом деле является экземпляром объекта.

objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0)); 

Вы также можете создать функцию динамической сортировки, которая сортирует объекты по их значению, которое вы pass:

function dynamicSort(property) {
    var sortOrder = 1;
    if(property[0] === "-") {
        sortOrder = -1;
        property = property.substr(1);
    }
    return function (a,b) {
        /* next line works with strings and numbers, 
         * and you may want to customize it to your needs
         */
        var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
        return result * sortOrder;
    }
}

В JavaScript есть своего рода соглашение, которое вы

var People = [
    {Name: "Name", Surname: "Surname"},
    {Name:"AAA", Surname:"ZZZ"},
    {Name: "Name", Surname: "AAA"}
];

измените

People.sort(dynamicSort("Name"));
People.sort(dynamicSort("Surname"));
People.sort(dynamicSort("-Surname"));

Это выражение немедленного вызова функции в Javascript: он не работает с несколькими параметрами Глядя на вывод

Другие ответы, опубликованные здесь, лучше, но вот альтернатива:

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

function dynamicSortMultiple() {
    /*
     * save the arguments object as it will be overwritten
     * note that arguments object is an array-like object
     * consisting of the names of the properties to sort by
     */
    var props = arguments;
    return function (obj1, obj2) {
        var i = 0, result = 0, numberOfProperties = props.length;
        /* try getting a different result from 0 (equal)
         * as long as we have extra properties to compare
         */
        while(result === 0 && i < numberOfProperties) {
            result = dynamicSort(props[i])(obj1, obj2);
            i  ;
        }
        return result;
    }
}

Уже есть несколько хороших ответов, но я нашел их излишне сложными и трудными для понимания. Это короткий, простой и возвращает простой ассоциативный массив с именами ключей, соответствующими именам токенов в URL.

People.sort(dynamicSortMultiple("Name", "-Surname"));

Значение подкласса Array

Для тех, кому повезло, кто может использовать ES6, который позволяет расширять нативные объекты:

class MyArray extends Array {
    sortBy(...args) {
        return this.sort(dynamicSortMultiple.apply(null, args));
    }
}

).

MyArray.from(People).sortBy("Name", "-Surname");

В ES6 / ES2015 или новее вы можете сделать это следующим образом:

objs.sort((a, b) => a.last_nom.localeCompare(b.last_nom));

Underscore.js

, его можно использовать через

sortBy_.sortBy (list, iterator, [context]) Возвращает отсортированную копию списка, ранжированного в порядке возрастания по результатам выполнения каждого значения через итератор. Итератор также может быть строковое имя свойства для сортировки (например, длина).

var objs = [ 
  { first_nom: 'Lazslo',last_nom: 'Jamf' },
  { first_nom: 'Pig', last_nom: 'Bodine'  },
  { first_nom: 'Pirate', last_nom: 'Prentice' }
];

var sortedObjs = _.sortBy( objs, 'first_nom' );

Не понимаю, почему люди так усложняют:

objs.sort(function(a, b){
  return a.last_nom > b.last_nom;
});

Для более строгих движков: событие

objs.sort(function(a, b){
  return a.last_nom == b.last_nom ? 0 :  (a.last_nom > b.last_nom) || -1;
});

. Если вы открываете html-файл из локального файла, вы должны создать локальный сервер для обслуживания этого html-файла. Самый простой способ — использовать

. Если у вас есть повторяющиеся фамилии, вы можете отсортировать их по имени-

obj.sort(function(a,b){
  if(a.last_nom< b.last_nom) return -1;
  if(a.last_nom >b.last_nom) return 1;
  if(a.first_nom< b.first_nom) return -1;
  if(a.first_nom >b.first_nom) return 1;
  return 0;
});

Простое и быстрое решение к этой проблеме, используя наследование прототипа:

Array.prototype.sortBy = function(p) {
  return this.slice(0).sort(function(a,b) {
    return (a[p] > b[p]) ? 1 : (a[p] < b[p]) ? -1 : 0;
  });
}

Пример / Использование

objs = [{age:44,name:'vinay'},{age:24,name:'deepak'},{age:74,name:'suresh'}];

objs.sortBy('age');
// Returns
// [{"age":24,"name":"deepak"},{"age":44,"name":"vinay"},{"age":74,"name":"suresh"}]

objs.sortBy('name');
// Returns
// [{"age":24,"name":"deepak"},{"age":74,"name":"suresh"},{"age":44,"name":"vinay"}]

Update: В этом примере проверяется наличие тега

вместо использования пользовательской функции сравнения вы также можете создать тип объекта с пользовательским toString().

function Person(firstName, lastName) {
    this.firtName = firstName;
    this.lastName = lastName;
}

Person.prototype.toString = function() {
    return this.lastName   ', '   this.firstName;
}

var persons = [ new Person('Lazslo', 'Jamf'), ...]
persons.sort();

. По состоянию на 2018 год существует гораздо более короткое и элегантное решение. Просто используйте. Array.prototype.sort () Глядя на вывод

Пример:

var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic', value: 13 },
  { name: 'Zeros', value: 37 }
];

// sort by value
items.sort(function (a, b) {
  return a.value - b.value;
});

Lodash.js (расширенный вариант Underscore.js С чем вы столкнулись

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

Lodash создает очень чистый код и способствует более функциональному программированию стиль, который приводит к меньшему количеству ошибок. С одного взгляда становится ясно, каково намерение, если код.

Проблема OP может быть просто решена следующим образом:

const sortedObjs = _.sortBy(objs, 'last_nom');

синтаксис скобок с

const users = [
  { 'user': {'name':'fred', 'age': 48}},
  { 'user': {'name':'barney', 'age': 36 }},
  { 'user': {'name':'wilma'}},
  { 'user': {'name':'betty', 'age': 32}}
];

Теперь мы можем использовать _. property http: //www.html5rocks.com/en/tutorials/file/filesystem/ user.age чтобы указать путь к свойству, которое должно соответствовать. Мы отсортируем пользовательские объекты по вложенному свойству age. Да, это позволяет сопоставлять вложенные свойства!

const sortedObjs = _.sortBy(users, ['user.age']);

Проблема с URL-адресами недавнее примечание: Глядя на вывод

const sortedObjs = _.reverse(_.sortBy(users, ['user.age']));

Хотите объединить оба, используя связывать ?

const sortedObjs = _.chain(users).sortBy('user.age').reverse().value();

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

Самый простой способ: Lodash

Обратите внимание, что для тех, кто использует новый https://lodash.com/docs/4.17.10 # orderBy С чем вы столкнулись

здесь есть версия для

Arguments

collection (Array | Object): коллекция для итерации. [iteratees = [_. identity]] (Array [] | Function [] | Object [] | string []): итерации для сортировки. [ orders] (string []): порядок сортировки итераций.

ответ, который сообщает браузеру разрешить коду из любого источника доступ к ресурсу будет включать следующее:

(массив): возвращает новый отсортированный массив.


var _ = require('lodash');
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":"6",
     "city":"Dallas",
     "state":"TX",
     "zip":"75000",
     "price":"556699"},
    {"h_id":"5",
     "city":"New York",
     "state":"NY",
     "zip":"00010",
     "price":"962500"}
    ];

_.orderBy(homes, ['city', 'state', 'zip'], ['asc', 'desc', 'asc']);

. Здесь есть много хороших ответов, но я бы хотел хотелось бы отметить, что они могут быть расширены очень просто, чтобы добиться гораздо более сложной сортировки. Единственное, что вам нужно сделать, это использовать оператор OR для цепочки функций сравнения, например:

objs.sort((a,b)=> fn1(a,b) || fn2(a,b) || fn3(a,b) )

Как указывают @squint и @mekdev, вы получаете лучшая производительность, сначала создав функцию вне цикла, а затем связав результаты внутри цикла. fn1, fn2, … — функции сортировки, которые возвращают [-1 , 0,1]. Это приводит к «сортировке по fn1», «сортировке по fn2», которая в значительной степени равна ORDER BY в SQL.

Это решение основано на поведении ||, который оценивается как первое оцененное выражение, которое можно преобразовать в истинное Глядя на вывод

Простейшая форма содержит только одну встроенную функцию, подобную этой:

// ORDER BY last_nom
objs.sort((a,b)=> a.last_nom.localeCompare(b.last_nom) )

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

// ORDER_BY last_nom, first_nom
objs.sort((a,b)=> a.last_nom.localeCompare(b.last_nom) || 
                  a.first_nom.localeCompare(b.first_nom)  )

способ сделать это: может выглядеть примерно так:

// ORDER BY <n>
let cmp = (a,b,n)=>a[n].localeCompare(b[n])

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

. Вы можете использовать его с цепочкой их по приоритету сортировки:

// ORDER_BY last_nom, first_nom
objs.sort((a,b)=> cmp(a,b, "last_nom") || cmp(a,b, "first_nom") )
// ORDER_BY last_nom, first_nom DESC
objs.sort((a,b)=> cmp(a,b, "last_nom") || -cmp(a,b, "first_nom") )
// ORDER_BY last_nom DESC, first_nom DESC
objs.sort((a,b)=> -cmp(a,b, "last_nom") || -cmp(a,b, "first_nom") )

Дело в том, что чистый JavaScript с функциональным подходом может проделать долгий путь без внешних библиотек или сложного кода. Это также очень эффективно, так как не нужно выполнять разбор строк

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

objs.sort(sortBy('last_nom'));

:

/**
 * @description
 * Returns a function which will sort an
 * array of objects by the given key.
 *
 * @param  {String}  key
 * @param  {Boolean} reverse
 * @return {Function}
 */
const sortBy = (key, reverse) => {

  // Move smaller items towards the front
  // or back of the array depending on if
  // we want to sort the array in reverse
  // order or not.
  const moveSmaller = reverse ? 1 : -1;

  // Move larger items towards the front
  // or back of the array depending on if
  // we want to sort the array in reverse
  // order or not.
  const moveLarger = reverse ? -1 : 1;

  /**
   * @param  {*} a
   * @param  {*} b
   * @return {Number}
   */
  return (a, b) => {
    if (a[key] < b[key]) {
      return moveSmaller;
    }
    if (a[key] > b[key]) {
      return moveLarger;
    }
    return 0;
  };
};

глючит в iOS

arr.sort((a, b) => a.name > b.name)

и, следовательно,

, я не видел, чтобы этот конкретный подход предлагался, поэтому вот краткий метод сравнения, который мне нравится использовать, который подходит для обоих string и number:

const objs = [ 
  { first_nom: 'Lazslo', last_nom: 'Jamf'     },
  { first_nom: 'Pig',    last_nom: 'Bodine'   },
  { first_nom: 'Pirate', last_nom: 'Prentice' }
];

const sortBy = fn => (a, b) => {
  const fa = fn(a)
  const fb = fn(b)
  return -(fa < fb) ||  (fa > fb)
}
const getLastName = o => o.last_nom
const sortByLastName = sortBy(getLastName)

objs.sort(sortByLastName)
console.log(objs.map(getLastName))

для JavaScript на стороне сервера), или используйте «Polyfill». Polyfill для этой функциональности, однако, тривиален, и, поскольку он делает код более легким для чтения, его стоит включить в Polyfill. sortBy():

sortBy() принимает fn, который выбирает какое значение из объекта для использования в качестве сравнения и возвращает функцию, которую можно передать непосредственно в Array.prototype.sort(), который я могу захватить после ввода значений событие запускается, но когда элементы динамически добавляются в модальный div, событие больше не запускается, когда пользователь вводит свой текст. o.last_nom jQuery.each Array.prototype.sort(), например,

{ first_nom: 'Lazslo', last_nom: 'Jamf' }

Если вы играете с этой демонстрацией более минуты, вы должны быстро начать видеть проблемы.

{ first_nom: 'Pig', last_nom: 'Bodine' }

мы используем

(a, b) => {
  const fa = fn(a)
  const fb = fn(b)
  return -(fa < fb) ||  (fa > fb)
}

чтобы сравнить их.

, мы можем расширить функцию сравнения до эквивалентного fn = o => o.last_nom для цикла заслуживает упоминания здесь:

(a, b) => {
  const fa = a.last_nom
  const fb = b.last_nom
  return -(fa < fb) ||  (fa > fb)
}

Преимущества: переменная || имеет функцию короткого замыкания, которая очень полезна здесь. Из-за того, как это работает, тело функции выше означает, что

if (fa < fb) return -1
return  (fa > fb)

Console.log (Date.parse («13 июня 2018 10:50:39 GMT 1»)) ; fa < fb Установка: -1, в противном случае, если fa > fb, затем мы возвращаем 1 Для замены несколько раз используйте: fa == fb с вашим объектом fa < fb и fa > fb Вы можете клонировать объект и удалить любую ссылку из предыдущего, используя одну строку кода. Просто выполните: false ;, затем использует 0 Глядя на вывод

добавлен бонус, вот эквивалент в ECMAScript 5 без функций стрелок, который, к сожалению, более многословен:

var objs = [ 
  { first_nom: 'Lazslo', last_nom: 'Jamf'     },
  { first_nom: 'Pig',    last_nom: 'Bodine'   },
  { first_nom: 'Pirate', last_nom: 'Prentice' }
];

var sortBy = function (fn) {
  return function (a, b) {
    var fa = fn(a)
    var fb = fn(b)
    return -(fa < fb) ||  (fa > fb)
  }
}

var getLastName = function (o) { return o.last_nom }
var sortByLastName = sortBy(getLastName)

objs.sort(sortByLastName)
console.log(objs.map(getLastName))

, и, как упоминалось в @CMS, он не будет кодировать каждый символ. Ребята из
Эта версия основана на или повторно обработать Глядя на вывод

function sortByAttribute(array, ...attrs) {
  // generate an array of predicate-objects contains
  // property getter, and descending indicator
  let predicates = attrs.map(pred => {
    let descending = pred.charAt(0) === '-' ? -1 : 1;
    pred = pred.replace(/^-/, '');
    return {
      getter: o => o[pred],
      descend: descending
    };
  });
  // schwartzian transform idiom implementation. aka: "decorate-sort-undecorate"
  return array.map(item => {
    return {
      src: item,
      compareValues: predicates.map(predicate => predicate.getter(item))
    };
  })
  .sort((o1, o2) => {
    let i = -1, result = 0;
    while (  i < predicates.length) {
      if (o1.compareValues[i] < o2.compareValues[i]) result = -1;
      if (o1.compareValues[i] > o2.compareValues[i]) result = 1;
      if (result *= predicates[i].descend) break;
    }
    return result;
  })
  .map(item => item.src);
}

Вот пример, как его использовать: у тега

let games = [
  { name: 'Pako',              rating: 4.21 },
  { name: 'Hill Climb Racing', rating: 3.88 },
  { name: 'Angry Birds Space', rating: 3.88 },
  { name: 'Badland',           rating: 4.33 }
];

// sort by one attribute
console.log(sortByAttribute(games, 'name'));
// sort by mupltiple attributes
console.log(sortByAttribute(games, '-rating', 'name'));

@ ege-Özcan

Более подключаемая версия на основе блоков @ ege-Özcan очень хорошо , но не Глядя на вывод

в правиле. Так как я не нашел ничего приличного в этом роде, я написал простой инструмент для решения проблемы.

, с которым я столкнулся ниже и не мог изменить Это. Я также не хотел временно сплющивать объект. Также я не хотел использовать подчеркивание / lodash, в основном из соображений производительности и удовольствия, чтобы реализовать это самостоятельно.

var People = [
   {Name: {name: "Name", surname: "Surname"}, Middlename: "JJ"},
   {Name: {name: "AAA", surname: "ZZZ"}, Middlename:"Abrams"},
   {Name: {name: "Name", surname: "AAA"}, Middlename: "Wars"}
];

Цель

Цель состоит в том, чтобы отсортировать его в первую очередь по People.Name.name и, во-вторых, People.Name.surname

Препятствия

Теперь в базовом решении используются скобочные обозначения для вычисления свойств, которые нужно сортировать динамически. Здесь, однако, мы должны были бы также динамически создавать обозначение в скобках, так как можно ожидать, что некоторые типа People['Name.name'] будет работать — что не работает.

Просто сделав People['Name']['name'] не будет влиять на n — й уровень.

Решение

Обратите внимание, что для того, чтобы это работало, каждому из ваших входных данных потребуется

var People = [
   {Name: {name: "Name", surname: "Surname"}, Middlename: "JJ"},
   {Name: {name: "AAA", surname: "ZZZ"}, Middlename:"Abrams"},
   {Name: {name: "Name", surname: "AAA"}, Middlename: "Wars"}
];

People.sort(dynamicMultiSort(['Name','name'], ['Name', '-surname']));
// Results in...
// [ { Name: { name: 'AAA', surname: 'ZZZ' }, Middlename: 'Abrams' },
//   { Name: { name: 'Name', surname: 'Surname' }, Middlename: 'JJ' },
//   { Name: { name: 'Name', surname: 'AAA' }, Middlename: 'Wars' } ]

// same logic as above, but strong deviation for dynamic properties 
function dynamicSort(properties) {
  var sortOrder = 1;
  // determine sort order by checking sign of last element of array
  if(properties[properties.length - 1][0] === "-") {
    sortOrder = -1;
    // Chop off sign
    properties[properties.length - 1] = properties[properties.length - 1].substr(1);
  }
  return function (a,b) {
    propertyOfA = recurseObjProp(a, properties)
    propertyOfB = recurseObjProp(b, properties)
    var result = (propertyOfA < propertyOfB) ? -1 : (propertyOfA > propertyOfB) ? 1 : 0;
    return result * sortOrder;
  };
}

/**
 * Takes an object and recurses down the tree to a target leaf and returns it value
 * @param  {Object} root - Object to be traversed.
 * @param  {Array} leafs - Array of downwards traversal. To access the value: {parent:{ child: 'value'}} -> ['parent','child']
 * @param  {Number} index - Must not be set, since it is implicit.
 * @return {String|Number}       The property, which is to be compared by sort.
 */
function recurseObjProp(root, leafs, index) {
  index ? index : index = 0
  var upper = root
  // walk down one level
  lower = upper[leafs[index]]
  // Check if last leaf has been hit by having gone one step too far.
  // If so, return result from last step.
  if (!lower) {
    return upper
  }
  // Else: recurse!
  index  
  // HINT: Bug was here, for not explicitly returning function
  // https://stackoverflow.com/a/17528613/3580261
  return recurseObjProp(lower, leafs, index)
}

/**
 * Multi-sort your array by a set of properties
 * @param {...Array} Arrays to access values in the form of: {parent:{ child: 'value'}} -> ['parent','child']
 * @return {Number} Number - number for sort algorithm
 */
function dynamicMultiSort() {
  var args = Array.prototype.slice.call(arguments); // slight deviation to base

  return function (a, b) {
    var i = 0, result = 0, numberOfProperties = args.length;
    // REVIEW: slightly verbose; maybe no way around because of `.sort`-'s nature
    // Consider: `.forEach()`
    while(result === 0 && i < numberOfProperties) {
      result = dynamicSort(args[i])(a, b);
      i  ;
    }
    return result;
  }
}

Пример

Рабочий пример в JSBin

Еще один вариант:

var someArray = [...];

function generateSortFn(prop, reverse) {
    return function (a, b) {
        if (a[prop] < b[prop]) return reverse ? 1 : -1;
        if (a[prop] > b[prop]) return reverse ? -1 : 1;
        return 0;
    };
}

someArray.sort(generateSortFn('name', true));

сортирует по возрастанию по умолчанию.

Простым способом:

objs.sort(function(a,b) {
  return b.last_nom.toLowerCase() < a.last_nom.toLowerCase();
});

Посмотрите на обратную косую черту '.toLowerCase()' необходим для предотвращения ошибок при сравнении строк.

дополнительные параметры desc для Ege Özcan Во-первых,

function dynamicSort(property, desc) {
    if (desc) {
        return function (a, b) {
            return (a[property] > b[property]) ? -1 : (a[property] < b[property]) ? 1 : 0;
        }   
    }
    return function (a, b) {
        return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
    }
}

работает:

Array.prototype.sortBy = function() {
    function _sortByAttr(attr) {
        var sortOrder = 1;
        if (attr[0] == "-") {
            sortOrder = -1;
            attr = attr.substr(1);
        }
        return function(a, b) {
            var result = (a[attr] < b[attr]) ? -1 : (a[attr] > b[attr]) ? 1 : 0;
            return result * sortOrder;
        }
    }
    function _getSortFunc() {
        if (arguments.length == 0) {
            throw "Zero length arguments not allowed for Array.sortBy()";
        }
        var args = arguments;
        return function(a, b) {
            for (var result = 0, i = 0; result == 0 && i < args.length; i  ) {
                result = _sortByAttr(args[i])(a, b);
            }
            return result;
        }
    }
    return this.sort(_getSortFunc.apply(null, arguments));
}

Использование:

// Utility for printing objects
Array.prototype.print = function(title) {
    console.log("************************************************************************");
    console.log("**** " title);
    console.log("************************************************************************");
    for (var i = 0; i < this.length; i  ) {
        console.log("Name: " this[i].FirstName, this[i].LastName, "Age: " this[i].Age);
    }
}

// Setup sample data
var arrObj = [
    {FirstName: "Zach", LastName: "Emergency", Age: 35},
    {FirstName: "Nancy", LastName: "Nurse", Age: 27},
    {FirstName: "Ethel", LastName: "Emergency", Age: 42},
    {FirstName: "Nina", LastName: "Nurse", Age: 48},
    {FirstName: "Anthony", LastName: "Emergency", Age: 44},
    {FirstName: "Nina", LastName: "Nurse", Age: 32},
    {FirstName: "Ed", LastName: "Emergency", Age: 28},
    {FirstName: "Peter", LastName: "Physician", Age: 58},
    {FirstName: "Al", LastName: "Emergency", Age: 51},
    {FirstName: "Ruth", LastName: "Registration", Age: 62},
    {FirstName: "Ed", LastName: "Emergency", Age: 38},
    {FirstName: "Tammy", LastName: "Triage", Age: 29},
    {FirstName: "Alan", LastName: "Emergency", Age: 60},
    {FirstName: "Nina", LastName: "Nurse", Age: 54}
];

//Unit Tests
arrObj.sortBy("LastName").print("LastName Ascending");
arrObj.sortBy("-LastName").print("LastName Descending");
arrObj.sortBy("LastName", "FirstName", "-Age").print("LastName Ascending, FirstName Ascending, Age Descending");
arrObj.sortBy("-FirstName", "Age").print("FirstName Descending, Age Ascending");
arrObj.sortBy("-Age").print("Age Descending");

Согласно вашему примеру, вам нужно отсортировать по двум полям (фамилия, имя), а не по одному. Ты можешь использовать Alasql Как узнать количество дней между двумя даты в JavaScript? — Переполнение стека

var res = alasql('SELECT * FROM ? ORDER BY last_nom, first_nom',[objs]);

Метод, который бы направлял всплеск события к родительским элементам. (Есть небольшие различия между ними, но они важны только в том случае, если вы используете свойство Глядя на вывод

objs.sort(function(a,b){return b.last_nom>a.last_nom})

Простая функция, которая сортирует массив объектов по свойству

function sortArray(array, property, direction) {
    direction = direction || 1;
    array.sort(function compare(a, b) {
        let comparison = 0;
        if (a[property] > b[property]) {
            comparison = 1 * direction;
        } else if (a[property] < b[property]) {
            comparison = -1 * direction;
        }
        return comparison;
    });
    return array; // Chainable
}

Если пользовательский агент содержит «Mobi» (согласно MDN) и доступен ontouchstart, то, скорее всего, это мобильное устройство.

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

sortArray(objs, "last_nom"); // Asc
sortArray(objs, "last_nom", -1); // Desc

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

objs.sort(function (a,b) {

var nameA=a.last_nom.toLowerCase(), nameB=b.last_nom.toLowerCase()

if (nameA < nameB)
  return -1;
if (nameA > nameB)
  return 1;
return 0;  //no sorting

})
function compare(propName) {
    return function(a,b) {
        if (a[propName] < b[propName])
            return -1;
        if (a[propName] > b[propName])
            return 1;
        return 0;
    };
}

objs.sort(compare("last_nom"));

Учитывая оригинальный пример:

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

, если вам интересно больше узнать о концепции. Вы можете пройти дальше.

objs.sort(function(left, right) {
    var last_nom_order = left.last_nom.localeCompare(right.last_nom);
    var first_nom_order = left.first_nom.localeCompare(right.first_nom);
    return last_nom_order || first_nom_order;
});

Оператор Notes

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

function sortObjectsArray(objectsArray, sortKey)
        {
            // Quick Sort:
            var retVal;

            if (1 < objectsArray.length)
            {
                var pivotIndex = Math.floor((objectsArray.length - 1) / 2);  // middle index
                var pivotItem = objectsArray[pivotIndex];                    // value in the middle index
                var less = [], more = [];

                objectsArray.splice(pivotIndex, 1);                          // remove the item in the pivot position
                objectsArray.forEach(function(value, index, array)
                {
                    value[sortKey] <= pivotItem[sortKey] ?                   // compare the 'sortKey' proiperty
                        less.push(value) :
                        more.push(value) ;
                });

                retVal = sortObjectsArray(less, sortKey).concat([pivotItem], sortObjectsArray(more, sortKey));
            }
            else
            {
                retVal = objectsArray;
            }

            return retVal;
        }

Использовать пример:

var myArr = 
        [
            { val: 'x', idx: 3 },
            { val: 'y', idx: 2 },
            { val: 'z', idx: 5 },
        ];
myArr = sortObjectsArray(myArr, 'idx');

/ Handle Response /

XUL

import R from 'ramda'
var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];
var ascendingSortedObjs = R.sortBy(R.prop('last_nom'), objs)
var descendingSortedObjs = R.reverse(ascendingSortedObjs)

Я только что улучшил динамическую сортировку Ege Özcan , чтобы погрузиться глубоко в объекты. Если данные выглядят так:

obj = [
    {
        a: { a: 1, b: 2, c: 3 },
        b: { a: 4, b: 5, c: 6 }
    },
    { 
        a: { a: 3, b: 2, c: 1 },
        b: { a: 6, b: 5, c: 4 }
}];

И если вы хотите отсортировать его по a.a , я думаю, мое улучшение очень хорошо помогает. Я добавляю новые функциональные возможности к таким объектам:

Object.defineProperty(Object.prototype, 'deepVal', {
    enumerable: false,
    writable: true,
    value: function (propertyChain) {
        var levels = propertyChain.split('.');
        parent = this;
        for (var i = 0; i < levels.length; i  ) {
            if (!parent[levels[i]])
                return undefined;
            parent = parent[levels[i]];
        }
        return parent;
    }
});

и изменен _ dynamicSort временное мышление, как у разработчика на стороне клиента. Мы должны подумать о том, как разделить наше приложение на отдельные, расширяемые, тестируемые компоненты. для вызова закрытия. Function:

return function (a,b) {
        var result = ((a.deepVal(property) > b.deepVal(property)) - (a.deepVal(property) < b.deepVal(property)));
        return result * sortOrder;
    }

И теперь вы можете сортировать по aa У DanSingerman есть очень хорошее решение для этого вопроса.

obj.sortBy('a.a');

См. скрипт Commplete в JSFiddle

, несколько абзацев под большой таблицей в начале этого раздела), где говорится:

Предостережение для предоставленных хостом объектов

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

Как их отсортировать по значению last_nom Итак, в качестве третьей альтернативы вышеприведенному, использование атрибутов данных для декларативного объявления поведения в разметке. Поведение скрыто от глаз, но сразу видно, что происходит.

ложное имя как для супруга, так и для возраста, Вы можете продолжить. В противном случае у вас есть только одно поле со значением (или с очень ранним браком), и вам нужно создать дополнительную ошибку в вашей sort(a,b), но это только работает строки и числа. Нужно ли добавлять toString() JSON.parse () преобразует любую строку JSON, переданную в функцию, в объект JSON.

массивов xPrototype : https://github.com/reduardo7/ xPrototype / blob / master / README.md # sortbycol1-col2-coln

var o = [ 
  { Name: 'Lazslo', LastName: 'Jamf'     },
  { Name: 'Pig',    LastName: 'Bodine'   },
  { Name: 'Pirate', LastName: 'Prentice' },
  { Name: 'Pag',    LastName: 'Bodine'   }
];


// Original
o.each(function (a, b) { console.log(a, b); });
/*
 0 Object {Name: "Lazslo", LastName: "Jamf"}
 1 Object {Name: "Pig", LastName: "Bodine"}
 2 Object {Name: "Pirate", LastName: "Prentice"}
 3 Object {Name: "Pag", LastName: "Bodine"}
*/


// Sort By LastName ASC, Name ASC
o.sortBy('LastName', 'Name').each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pag", LastName: "Bodine"}
 1 Object {Name: "Pig", LastName: "Bodine"}
 2 Object {Name: "Lazslo", LastName: "Jamf"}
 3 Object {Name: "Pirate", LastName: "Prentice"}
*/


// Sort by LastName ASC and Name ASC
o.sortBy('LastName'.asc, 'Name'.asc).each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pag", LastName: "Bodine"}
 1 Object {Name: "Pig", LastName: "Bodine"}
 2 Object {Name: "Lazslo", LastName: "Jamf"}
 3 Object {Name: "Pirate", LastName: "Prentice"}
*/


// Sort by LastName DESC and Name DESC
o.sortBy('LastName'.desc, 'Name'.desc).each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pirate", LastName: "Prentice"}
 1 Object {Name: "Lazslo", LastName: "Jamf"}
 2 Object {Name: "Pig", LastName: "Bodine"}
 3 Object {Name: "Pag", LastName: "Bodine"}
*/


// Sort by LastName DESC and Name ASC
o.sortBy('LastName'.desc, 'Name'.asc).each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pirate", LastName: "Prentice"}
 1 Object {Name: "Lazslo", LastName: "Jamf"}
 2 Object {Name: "Pag", LastName: "Bodine"}
 3 Object {Name: "Pig", LastName: "Bodine"}
*/

Путь 1:

в любой функции объекта для ссылки на другие свойства этого объекта. Это не то же самое, что экземпляр, созданный с помощью Underscore.js. Импортировать подчеркивание первым.

 import * as _ from 'underscore';
 let SortedObjs = _.sortBy(objs, 'last_nom');

В этом примере

function compare(first, second) {
     if (first.last_nom < second.last_nom)
         return -1;
     if (first.last_nom > second.last_nom)
       return 1;
    return 0;
 }

objs.sort(compare);

Использование lodash или Подчеркни, это просто кусок

> const sortedList = _.orderBy(objs, [last_nom], [asc]); // asc or desc

Меня устраивает. Здесь будет сохраняться В дополнение к — максимальный предел символов

 function sort(items, property, direction) {

    function compare(a, b) {
      if(!a[property] && !b[property]) {
        return 0;
      } else if(a[property] && !b[property]) {
        return -1;
      } else if(!a[property] && b[property]) {
        return 1;
      } else {
        const value1 = a[property].toString().toUpperCase(); // ignore upper and lowercase
        const value2 = b[property].toString().toUpperCase(); // ignore upper and lowercase
        if (value1 < value2) {
          return direction === 0 ? -1 : 1;
        } else if (value1 > value2) {
          return direction === 0 ? 1 : -1;
        } else {
          return 0;
        }
        
      }
    }
    
    return items.sort(compare);
   } 
   
   var items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: undefined, value: -12 },
  { name: 'Magnetic', value: 13 },
  { name: 'Zeros', value: 37 }
];
   console.log('Ascending Order:- ');
   console.log(sort(items, 'name', 0));
   console.log('Decending Order:- ');
   console.log(sort(items, 'name', 1));
    
    

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

Копировать массив в ES6

///////////////////////example array of peoples ///////////////////////

var peoples = [
    {name: "Zach", surname: "Emergency", age: 1},
    {name: "Nancy", surname: "Nurse", age: 1},
    {name: "Ethel", surname: "Emergency", age: 1},
    {name: "Nina", surname: "Nurse", age: 42},
    {name: "Anthony", surname: "Emergency", age: 42},
    {name: "Nina", surname: "Nurse", age: 32},
    {name: "Ed", surname: "Emergency", age: 28},
    {name: "Peter", surname: "Physician", age: 58},
    {name: "Al", surname: "Emergency", age: 58},
    {name: "Ruth", surname: "Registration", age: 62},
    {name: "Ed", surname: "Emergency", age: 38},
    {name: "Tammy", surname: "Triage", age: 29},
    {name: "Alan", surname: "Emergency", age: 60},
    {name: "Nina", surname: "Nurse", age: 58}
];



//////////////////////// Sorting function /////////////////////
function sortPeoples(propertyArr, reverse) {
        function compare(a,b) {
            var i=0;
            while (propertyArr[i]) {
                if (a[propertyArr[i]] < b[propertyArr[i]])  return -1;
                if (a[propertyArr[i]] > b[propertyArr[i]])  return 1;
                i  ;
            }
            return 0;
            }
        peoples.sort(compare);
        if (reverse){
            peoples.reverse();
        }
    };

////////////////end of sorting method///////////////
function printPeoples(){
  $('#output').html('');
peoples.forEach( function(person){
 $('#output').append(person.surname " " person.name " " person.age "<br>");
} )
}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
  <html>
  <body>
<button onclick="sortPeoples(['surname']); printPeoples()">sort by ONLY by surname ASC results in mess with same name cases</button><br>
<button onclick="sortPeoples(['surname', 'name'], true); printPeoples()">sort by surname then name DESC</button><br>
<button onclick="sortPeoples(['age']); printPeoples()">sort by AGE ASC. Same issue as in first case</button><br>
<button onclick="sortPeoples(['age', 'surname']); printPeoples()">sort by AGE and Surname ASC. Adding second field fixed it.</button><br>
        
    <div id="output"></div>
    </body>
  </html>
// Sort Array of Objects

// Data
var booksArray = [
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

// Property to Sort By
var args = "last_nom";

// Function to Sort the Data by given Property
function sortByProperty(property) {
    return function (a, b) {
        var sortStatus = 0,
            aProp = a[property].toLowerCase(),
            bProp = b[property].toLowerCase();
        if (aProp < bProp) {
            sortStatus = -1;
        } else if (aProp > bProp) {
            sortStatus = 1;
        }
        return sortStatus;
    };
}

// Implementation
var sortedArray = booksArray.sort(sortByProperty(args));

console.log("sortedArray: "   JSON.stringify(sortedArray) );

В моем случае все символы, не входящие в ASCII, запрещены, поэтому я изменил исходное выражение, чтобы исключить все символы выше U 007F:

"sortedArray: 
[{"first_nom":"Pig","last_nom":"Bodine"},
{"first_nom":"Lazslo","last_nom":"Jamf"},
{"first_nom":"Pirate","last_nom":"Prentice"}]"

Использование CharCode с вызовом символа ASCII, что устранит место для ошибок в разных браузерах и операционных системах. Это также полезно для двуязычного использования (акценты и т. Д.). http://www.levihackwith.com / code-snippet-how-to-sort-an-array-of-json-objects-by-property /

Это отсортирует двухуровневый вложенный массив по свойству, переданному ему в алфавитно-цифровом порядке.

function sortArrayObjectsByPropAlphaNum(property) {
    return function (a,b) {
        var reA = /[^a-zA-Z]/g;
        var reN = /[^0-9]/g;
        var aA = a[property].replace(reA, '');
        var bA = b[property].replace(reA, '');

        if(aA === bA) {
            var aN = parseInt(a[property].replace(reN, ''), 10);
            var bN = parseInt(b[property].replace(reN, ''), 10);
            return aN === bN ? 0 : aN > bN ? 1 : -1;
        } else {
            return a[property] > b[property] ? 1 : -1;
        }
    };
}

Использование:

objs.sort(utils.sortArrayObjectsByPropAlphaNum('last_nom'));

Итак, вот один алгоритм сортировки, который может сортировать в любом порядке по всему массиву объектов любого типа без ограничения сравнения типов данных (т. е. Number, String) {* } Это напечатало бы «4».

function smoothSort(items,prop,reverse) {  
    var length = items.length;
    for (var i = (length - 1); i >= 0; i--) {
        //Number of passes
        for (var j = (length - i); j > 0; j--) {
            //Compare the adjacent positions
            if(reverse){
              if (items[j][prop] > items[j - 1][prop]) {
                //Swap the numbers
                var tmp = items[j];
                items[j] = items[j - 1];
                items[j - 1] = tmp;
            }
            }

            if(!reverse){
              if (items[j][prop] < items[j - 1][prop]) {
                  //Swap the numbers
                  var tmp = items[j];
                  items[j] = items[j - 1];
                  items[j - 1] = tmp;
              }
            }
        }
    }

    return items;
}
  • первый аргумент items потому что вы просто звоните

  • prop ключ объекта, по которому вы хотите отсортировать,

  • reverse , является логическим параметром, который при истинном значении приводит к возрастанию, а в ложном — возвращению по убыванию. { *} Технически, некоторые электронные письма могут содержать кавычки в разделе до того, как

я дам вам решение, реализующее алгоритм selectionSort, это просто и эффективно

var objs = [ 
{ first_nom: 'Lazslo', last_nom: 'Jamf'     },
{ first_nom: 'Pig',    last_nom: 'Bodine'   },
{ first_nom: 'Pirate', last_nom: 'Prentice' }
];


function selection_Sort(num) { 
 //console.log(num);  
 var temp, index;
 for (var i = 0; i <= num.length - 1; i  ) {
index = i;
for (var j = i   1; j <= num.length - 1; j  ) {
 // you can use first_nom/last_nom,any way you choose to sort

  if (num[j]. last_nom < num[index]. last_nom) {
    index = j;
  } 
}

//below is the swapping part
temp = num[i]. last_nom;
num[i]. last_nom = num[index]. last_nom;
num[index]. last_nom = temp;
 };
 console.log(num); 
 return num; 
  }
  selection_Sort(objs);

Приятно видеть такие замечательные ответы

в случае, если у вас есть вложенные объекты

const objs = [{
        first_nom: 'Lazslo',
        last_nom: 'Jamf',
        moreDetails: {
            age: 20
        }
    }, {
        first_nom: 'Pig',
        last_nom: 'Bodine',
        moreDetails: {
            age: 21
        }
    }, {
        first_nom: 'Pirate',
        last_nom: 'Prentice',
        moreDetails: {
            age: 22
        }
    }];

nestedSort = (prop1, prop2 = null, direction = 'asc') => (e1, e2) => {
        const a = prop2 ? e1[prop1][prop2] : e1[prop1],
            b = prop2 ? e2[prop1][prop2] : e2[prop1],
            sortOrder = direction === "asc" ? 1 : -1
        return (a < b) ? -sortOrder : (a > b) ? sortOrder : 0;
    }

и назовите это как

objs.sort(nestedSort("last_nom"));
objs.sort(nestedSort("last_nom", null, "desc"));
objs.sort(nestedSort("moreDetails", "age"));
objs.sort(nestedSort("moreDetails", "age", "desc"));

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

function sortByKey<O>(key: keyof O, decending: boolean = false): (a: O, b: O) => number {
    const order = decending ? -1 : 1;
    return (a, b): number => {
        const valA = a[key];
        const valB = b[key];
        if (valA < valB) {
            return -order;
        } else if (valA > valB) {
            return order;
        } else {
            return 0;
        }
    }
}

. Это может быть использовано в TypeScript следующим образом:

const test = [
    {
        id: 0,
    },
    {
        id: 2,
    }
]

test.sort(sortByKey('id')) // OK
test.sort(sortByKey('id1')) // ERROR
test.sort(sortByKey('')) // ERROR
Понравилась статья? Поделиться с друзьями:
JavaScript & TypeScript
Adblock
detector