Подтвердить что ты не робот

Сортировка по двум значениям, приоритетным для одного из них

Как мне отсортировать эти данные по значениям count и year в порядке возрастания по приоритету по значению count?

//sort this
var data = [
    { count: '12', year: '1956' },
    { count: '1', year: '1971' },
    { count: '33', year: '1989' },
    { count: '33', year: '1988' }
];
//to get this
var data = [
    { count: '1', year: '1971' },
    { count: '12', year: '1956' },
    { count: '33', year: '1988' },
    { count: '33', year: '1989' },
];
4b9b3361

Ответ 1

(Посмотрите jsfiddle)

data.sort(function (x, y) {
    var n = x.count - y.count;
    if (n !== 0) {
        return n;
    }

    return x.year - y.year;
});

Ответ 2

Простое решение:

data.sort(function (a, b) {
  return a.count - b.count || a.year - b.year;
});

Это работает, потому что, если счетчик отличается, то сортировка основана на этом. Если счетчик совпадает, первое выражение возвращает 0, которое преобразуется в значение false, и используется результат второго выражения (т.е. Сортировка основана на году).

Ответ 3

Вы можете использовать JavaScript .sort() метод массива ( попробуйте):

data.sort(function(a, b) {
    // Sort by count
    var dCount = a.count - b.count;
    if(dCount) return dCount;

    // If there is a tie, sort by year
    var dYear = a.year - b.year;
    return dYear;
});

Примечание. Это изменяет исходный массив. Если вам нужно сначала сделать копию, вы можете сделать это:

var dataCopy = data.slice(0);

Ответ 4

вам нужно решить эту проблему следующим образом

var customSort = function(name, type){
     return function(o, p){
         var a, b;
         if(o && p && typeof o === 'object' && typeof p === 'object'){
            a = o[name];
            b = p[name];
           if(a === b){
              return typeof type === 'function' ? type(o, p) : o;
           }

           if(typeof a=== typeof b){
              return a < b ? -1 : 1;
            }
          return typeof a < typeof b ? -1 : 1;
        }
     };

};

например:  data.sort(customSort ('year', customSort ('count')));

Ответ 5

Основанный на отличном @RobG простое решение, я создал функцию для сортировки по нескольким различным свойствам, используя JS2015 с ошибкой map + find:

let sortBy = (p, a) => a.sort((i, j) => p.map(v => i[v] - j[v]).find(r => r))

sortBy(['count', 'year'], data)

Кроме того, если вы предпочитаете, традиционную версию JS (используйте с осторожностью из-за найти совместимость в старых браузерах):

var sortBy = function (properties, targetArray) {
  targetArray.sort(function (i, j) {
    return properties.map(function (prop) {
      return i[prop] - j[prop];
    }).find(function (result) {
      return result;
    });
  });
};

Ответ 6

user this, где "count" → первый приоритет и "год" → второй приоритет

data.sort(function(a,b){
  return a['count']<b['count']?-1:(a['count']>b['count']?1:(a['year']<b['year']?-1:1));
});

Ответ 7

Если вы ищете сортировку строк в алфавитном порядке, а не в цифрах, вот примерная проблема и ее решение.

Пример: Массив массивов (finalArray) с первой записью путь к папке и вторая запись имени файла; сортируйте так, чтобы массив сначала располагался в папке, и в пределах одинаковых папок, по имени файла.

например. после сортировки вы ожидаете:

[['folder1', 'abc.jpg'], 
 ['folder1', 'xyz.jpg'],
 ['folder2', 'def.jpg'],
 ['folder2', 'pqr.jpg']]

Обратитесь к Array.prototype.sort() - compareFunction

finalArray.sort((x: any, y: any): number => {
  const folder1: string = x[0].toLowerCase();
  const folder2: string = y[0].toLowerCase();
  const file1: string = x[1].toLowerCase();
  const file2: string = y[1].toLowerCase();

  if (folder1 > folder2) {
    return 1;
  } else if (folder1 === folder2 && file1 > file2) {
    return 1;
  } else if (folder1 === folder2 && file1 === file2) {
    return 0;
  } else if (folder1 === folder2 && file1 < file2) {
    return -1;
  } else if (folder1 < folder2) {
    return -1;
  }
});

Имейте в виду, что "Z" предшествует "a" (сначала капители в соответствии с кодовой точкой Unicode), поэтому у меня есть toLowerCase(). Проблема, описанная выше, не решает, что "10abc" появится до "9abc".