Сортировать массив, который содержит число и строки - PullRequest
0 голосов
/ 28 декабря 2018

Я пытаюсь отсортировать массив, который содержит строки, числа и числа в виде строк (например, '1', '2').Я хочу отсортировать этот массив так, чтобы отсортированный массив сначала содержал числа, а затем строки, содержащие число, а затем строки.

var arr = [9,5,'2','ab','3',-1 ] // to be sorted
arr.sort()
// arr = [-1, 5, 9, "2", "3","ab"] // expected result
//arr = [-1, "2", 5, 9, "ab"] // actual result

Я также пробовал

var number =[];
var char =[];
arr.forEach(a=>{
 if(typeof a == 'number') number.push(a);
 else char.push(a);
})
arr = (number.sort((a,b)=> a>b)).concat(char.sort((a,b)=> a>b))
// arr = [-1, 5, 9, "2", "3","ab"] // expected result
//  arr = [-1, 5, 9, "2", "ab", "3"]// actual result

Ответы [ 11 ]

0 голосов
/ 25 апреля 2019

Мы можем использовать функцию localeCompare внутри функции sort, чтобы отсортировать массив как

var items = [3, 'rob', 'peter', 43, 0, -222];
console.log(items.sort((a, b) => {
  return a.toString().localeCompare(b.toString());
}));
0 голосов
/ 03 июля 2019

var myArray = [9, 5, '2', 'ab', '3', -1]
myArray.sort((a, b) => {
  let aTest = /^\d+$/.test(a);
  let bTest = /^\d+$/.test(b);
  if (aTest && bTest) {
    return parseInt(a) - parseInt(b);
  } else if (aTest) {
    return -1;
  } else if (bTest) {
    return 1;
  } else {
    return a > b ? 1 : -1;
  }
})

console.log(myArray)
0 голосов
/ 28 декабря 2018
var arr=[9,5,'2','ab','3',-1];
    var string_arr=[];
    var number_arr=[];
    var string_number_arr=[];
    for(var i=0;i<arr.length;i++)
    {

        if(typeof(arr[i])=='number')
        {
            number_arr.push(arr[i]);

        }
        else if((Number(arr[i]).toString())=="NaN")
        {
            string_number_arr.push(arr[i]);

        }
        else
        {
            string_arr.push(arr[i]);
        }

    }
    string_arr.sort();
    number_arr.sort();
    string_number_arr.sort();
    var arr=number_arr.concat(string_arr,string_number_arr);
    console.log(arr);
0 голосов
/ 03 января 2019

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

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

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

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

var arr = [90000, 5, '2', 'ab', 'aa', '3', -1] // to be sorted
arr.sort((a,b) => {
  if(typeof a === 'string') {
    let temp = 0
    for (let s of a) temp += s.charCodeAt(0)
    a = Math.pow(temp, 5)
  }
  if(typeof b === 'string') {
    let temp = 0
    for(let s of b) temp += s.charCodeAt(0)
    b = Math.pow(temp, 5)
  }
  return a - b
})

console.log(arr) // [-1, 5, 90000, "2", "3", "aa", "ab"]
0 голосов
/ 28 декабря 2018

Вероятно, самое короткое:

 arr.sort((a, b) => ((typeof b === "number") - (typeof a === "number")) || (a > b ? 1 : -1));
0 голосов
/ 28 декабря 2018

Вы можете использовать метод Array .sort () в любом случае.

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

Пример:

// First of all discretize all kinds of data you want to deal with
function typeClassify(v) {
    return typeof v == "number"
        ? "N"
        : isNaN(v) ? "s" : "n"
        // (Treat all non numeric values as strings)
    ;
};


// Second: implement the sorting function
function sortCriteria(a, b) {
    var mode = typeClassify(a) + typeClassify(b);
    switch (mode) {
        case "NN":
            return a - b;
        case "nn":
            return Number(a) - Number(b);
        case "ss":
            return a == b
                ? 0
                : a > b
                    ? -1 : 1
            ;
        case "Nn":
        case "Ns":
        case "ns":
            return -1;
        case "nN":
        case "sN":
        case "sn":
            return 1;
        default:
            throw "This must never happen";
    };
};

// And finally provide that function as a callback for .sort() method
var arr = [9,5,'2','ab','3',-1 ] // to be sorted
console.log(arr.sort(sortCriteria));

// arr = [-1, 5, 9, "2", "3","ab"] // expected result
// arr = [ -1, 5, 9, '2', '3', 'ab' ] // obtained result

Очевидно, что функциональность typeClassify() функции может быть сведена к sortCriteria(), чтобы сохранить вызов функции при каждом сравнении.Я предпочел выделить это для ясности.

0 голосов
/ 28 декабря 2018

Сначала можно отсортировать целые числа, а затем нецелые, используя .filter() для разделения обоих типов данных.

См. Рабочий пример ниже (см. Пояснения к коду):

const arr = [9,5,'2','ab','3',-1];

const nums = arr.filter(n => typeof n == "number").sort(); // If the data type of a given element is a number store it in this array (and then sort)
const non_nums = arr.filter(x => typeof x != "number").sort(); // Store everything that is not a number in an array (and then sort)

const res = [...nums, ...non_nums]; // combine the two arrays
console.log(res); // [-1, 5, 9, "2", "3", "ab"]
0 голосов
/ 28 декабря 2018

Кажется, вы проделали большую часть работы со второй попытки.Все, что я здесь сделал, используется Array.concat, чтобы объединить отсортированные результаты number и char.

var arr = [9, 5, '2', 'ab', '3', -1] // to be sorted
var number = [];
var char = [];
arr.forEach(a => {
  if (typeof a == 'number') number.push(a);
  else char.push(a);
})


var sorted = number.sort().concat(char.sort());
console.log(sorted)
0 голосов
/ 28 декабря 2018

Попробуйте использовать это:

var arr = [9, 5, '2', 'ab', '3', -1];
var number = [];
var strInt = [];
var char = [];
arr.forEach(a => {
  if (typeof a === "number") {
    number.push(a);
  } else if (typeof a === "string" && /\d/.test(a)) {
    strInt.push(a);
  } else {
    char.push(a);
  }
});
arr = number.concat(strInt.concat(char));
console.log(arr);

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

0 голосов
/ 28 декабря 2018

Попробуйте это

const arr = [9, 5, '2', 'ab', '3', 'AB', -1];
const sortedArr = arr.sort((a, b) => {
    if (typeof a === 'number' && typeof b === 'number') {
        return a - b;
    } else if (typeof a === 'number') {
        return -1;
    } else if (typeof b === 'number') {
        return 1;
    } else {
        return a > b ? 1 : -1;
    }
});

console.log(sortedArr);

При этом используется дополнительная функция Array.prototype.sort для сортировки элементов в одном массиве.Он должен вернуть номер.Если число> 0, b идет первым.Если число <0, a идет первым.Если это 0, их позиция остается неизменной. </p>

...