тип агности c сортировка по javascript - PullRequest
0 голосов
/ 21 января 2020

Я пытаюсь, чтобы моя функция сортировки могла сортировать числа и строки в зависимости от заданного массива (тип массива неизвестен до времени выполнения)

Я знаю, что могу Выполните сортировку для массива чисел, выполнив:

myList = [1,4,6,2,3]
if (sortDirection == "ASC"){
  myList.sort(function(a, b){
    return a - b;
  }
}
else if (sortDirection == "DESC") {
  myList.sort(function(a, b){
    return b - a;
  }
}

, но myList также может быть списком строк, и это не будет работать. Я должен был бы сделать

myList = ["asdf", "sdfg", "dfgh"]
if (sortDirection == "ASC") {
  myList.sort();
}
else if (sortDirection == "DESC") {
  myList.sort();
  myList.reverse();
}

Я, конечно, могу сделать проверку типа, является ли список typeof string или typeof number и выполнить условия и иметь все эти случаи, но я чувствую, что есть лучший способ отформатировать Все это одновременно в противоположных направлениях.

Ответы [ 2 ]

0 голосов
/ 22 января 2020

Следуя рекомендациям @ Pointy , я сделал функцию сортировки на основе Int.Collator объекта Intl API . Метод String .localeCompare() похож на метод Collator .compare().

/**
 * @function sortChars(chars, desc, caps);
 * Sort an array of characters in a human readable order.
 *
 * @param  {Array}   chars An array of Strings and Numbers.
 * @param  {Boolean} desc  true - sort in descending order  
 * @default                false - sort in ascending order
 *                         
 * @param  {Boolean} caps  true - will place upper case letters first
 * @default                false - will place lower case letters first
 * @return {Array}         An array sorted by these criterion:
 *                         space: ' ', 
 *                         non-letters: '?', 
 *                         numbers: 99,⁰
 *                         lower case letter: 'l',¹
 *                         upper case letter: 'L'¹
 *
 *//* ⁰Contiguous groups of digits are considered at that value as a whole inside 
       a String or Number ex. ['1', 99, '100A']
      ¹The order of case can be changed by the third parameter
 */

const example = ['99', 98, 1, 'one', ' ', 'z', '♞', 'Ĉ', 'Z', 2112, '2111', 'a581', 'aa999999', '?', 'One', 'aA999999'];

const sortChars = (chars, desc, caps) => {

  // Ternary to determine case order
  let caseType = !caps ? "lower" : "upper";

  /*
  Initializing Collator Object
  numeric: true and sensitivity: "base" are required
  to evaluate Numbers properly
  Refer to: https://blog.praveen.science/natural-sorting-in-javascript/
  */
  const collator = new Intl.Collator(undefined, {
    caseFirst: caseType,
    numeric: true,
    sensitivity: "base"
  });
  // Uncomment statement below to see option values 
  // log(check(collator, desc));
  const ordered = chars.sort(collator.compare);

  // Ternary to determine the direction of returned array
  return !desc ? ordered : ordered.reverse();
};

// Sort ascending order
log(sortChars(example));

// Sort descending order
log(sortChars(example, true));

// Sort ascending order and upper case first
log(sortChars(example, false, true));

// Utility to review the options object
function check(collator, desc) {
  return Object.assign(Object.fromEntries(Object.entries(collator.resolvedOptions())), {
    descendingOrder: desc
  });
}

// Utility to log formatted entries to console
function log(data) {
  return console.log(JSON.stringify(data));
};
.as-console-wrapper {
  word-break: break-word
}
0 голосов
/ 21 января 2020

Самый простой ответ, который приходит мне в голову, - это просто без разбора делать сравнение строк при сортировке. Javascript поддерживает лексикографическое сравнение строк из коробки. Это означает, что 'Z' > 'A' вернет true. Смотрите здесь для получения дополнительной информации.

Следовательно, ваша функция сортировки может выглядеть следующим образом:

function sortArray(isDescending = true) {
  return (a, b) => {
     if(a.toString().toLowerCase() > b.toString().toLowerCase()) {
         if (isDescending) {
             return 1
         } else {
             return -1
         }
     } else {
         if (isDescending) {
            return -1
         } else {
            return 1
         }
  }
}

Тогда вы можете использовать свою функцию как это:

const myArrayOfStringsOrNumbers = ['A', 2, 'Bob', 18];
myArrayOfStringsOrNumbers.sort(sortArray(true));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...