Как отсортировать массив сначала по одному свойству, а затем по алфавиту в другом? - PullRequest
0 голосов
/ 07 февраля 2019
var sortedFeatures = features.sort(function(a,b){
    if(a.properties.Project_Year < b.properties.Project_Year) {return 1}
    if(a.properties.Project_Year > b.properties.Project_Year) {return -1 }
    return 0;
}) 

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

Теперь для второй части у меня есть атрибут с именем Project_Name.Я хочу, чтобы файлы сортировались по годам, но в такой сортировке я бы также хотел добавить сортировку по алфавиту.

Мой вывод уже установлен.Я хотел бы знать, как настроить этот код, чтобы получить правильный вид, который я ищу.

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

compareFunction сортирует features по Project_Year в порядке убывания.Если годы совпадают, разница равна нулю.Это значение falsy вынуждает его проверить второе условие и сравнить на основе Project_Name

var features = [
  { properties : { Project_Name : 'B', Project_Year : 2018 } },
  { properties : { Project_Name : 'A', Project_Year : 2018 } },
  { properties : { Project_Name : 'C', Project_Year : 2018 } },
  { properties : { Project_Name : 'A', Project_Year : 2019 } },
  { properties : { Project_Name : 'B', Project_Year : 2019 } },
];

var sortedFeatures = features.sort(function(a, b) {
  return b.properties.Project_Year - a.properties.Project_Year 
          || a.properties.Project_Name.localeCompare(b.properties.Project_Name)
})

console.log(sortedFeatures)

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

0 голосов
/ 07 февраля 2019

Это довольно простая задача.Просто сравните годы, если они совпадают, то сравните имена.

var features = [
  { Project_Name : 'C', properties : { Project_Year : new Date(2019, 1, 0) } },
  { Project_Name : 'A', properties : { Project_Year : new Date(2019, 1, 0) } },
  { Project_Name : 'B', properties : { Project_Year : new Date(2019, 1, 0) } },
  { Project_Name : 'C', properties : { Project_Year : new Date(2018, 1, 0) } },
  { Project_Name : 'A', properties : { Project_Year : new Date(2017, 1, 0) } },
  { Project_Name : 'B', properties : { Project_Year : new Date(2018, 1, 0) } }
];

/** Sort by year, followed by name */
var sortedFeatures = features.sort(function(a, b) {
  var yearDiff = a.properties.Project_Year - b.properties.Project_Year;
  if (yearDiff === 0) {
    return a.Project_Name.localeCompare(b.Project_Name);
  }
  return yearDiff;
});

console.log(sortedFeatures);
.as-console-wrapper { top: 0; max-height: 100% !important; }

Динамический подход

Если вы хотите более общую реализацию, вы можете проверить этот пример .Я создал расширенную реализацию этого примера, которая запрашивает область вложенных свойств.

var sort_by;
(function() {
  var default_cmp = (a, b) => a == b ? 0 : (a < b ? -1 : 1);
  getCmpFunc = (primer, reverse) => {
    let dfc = default_cmp, cmp = default_cmp;
    if (primer) {
      cmp = (a, b) => dfc(primer(a), primer(b));
    }
    if (reverse) {
      return (a, b) => -1 * cmp(a, b);
    }
    return cmp;
  };
  queryValue = function(v, scope) {
    return scope == null || scope.length === 0 ? v : queryValue(v[scope.shift()], scope);
  };
  sort_by = function() {
    let fields = [], n_fields = arguments.length, field, name, reverse, cmp;
    for (var i = 0; i < n_fields; i++) {
      field = arguments[i];
      if (typeof field === 'string') {
        name = field;
        cmp = default_cmp;
      } else {
        name = field.name;
        cmp = getCmpFunc(field.primer, field.reverse);
      }
      fields.push({ name: name, cmp: cmp });
    }
    return (A, B) => {
      let a, b, result;
      for (var i = 0; i < n_fields; i++) {
        result = 0;
        a = queryValue(A, fields[i].name.split('.'));
        b = queryValue(B, fields[i].name.split('.'));
        result = fields[i].cmp(a, b);
        if (result !== 0) break;
      }
      return result;
    };
  };
}());

var features = [
  { Project_Name : 'C', properties : { Project_Year : new Date(2019, 1, 0) } },
  { Project_Name : 'A', properties : { Project_Year : new Date(2019, 1, 0) } },
  { Project_Name : 'B', properties : { Project_Year : new Date(2019, 1, 0) } },
  { Project_Name : 'C', properties : { Project_Year : new Date(2018, 1, 0) } },
  { Project_Name : 'A', properties : { Project_Year : new Date(2017, 1, 0) } },
  { Project_Name : 'B', properties : { Project_Year : new Date(2018, 1, 0) } }
];

/** Sort by year (decending), followed by name (ascending) */
var sortedFeatures = features.sort(sort_by(
  { name: 'properties.Project_Year', reverse: true, primer : (d) => d.getTime() },
  'Project_Name' // scalar string value
));

console.log(sortedFeatures);
.as-console-wrapper {
  top: 0;
  max-height: 100% !important;
}
0 голосов
/ 07 февраля 2019

Хороший способ сделать это - посмотреть на часть return 0; вашего рода - это то, что происходит, когда свойства Project_Year одинаковы.Если вы замените это буквенным сравнением в свойстве Project_Name, вы должны получить желаемый ответ:

var sortedFeatures = features.sort(function(a,b){
   if(a.properties.Project_Year < b.properties.Project_Year) {return 1}
   if(a.properties.Project_Year > b.properties.Project_Year) {return -1 }

   //compare names alphabetically
   return a.properties.Project_Name.localeCompare(b.properties.Project_Name);
});

Обратите внимание, что это не относится к случаю, когда Project_Name недопустимострока (например, undefined или null), и в этом случае программа выдаст ошибку, поэтому, если это допустимая возможность, добавьте туда несколько операторов if(), чтобы защититься от нее, например,

var sortedFeatures = features.sort(function(a,b){
   if(a.properties.Project_Year < b.properties.Project_Year) {return 1}
   if(a.properties.Project_Year > b.properties.Project_Year) {return -1 }

   //compare names alphabetically
   const projectNameA = a.properties.Project_Name || ""; //default to empty string
   const projectNameB = b.properties.Project_Name || ""; 
   return projectNameA.localeCompare(projectNameB);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...