web-dev-qa-db-fra.com

Trier un tableau contenant un nombre et des chaînes

J'essaie de trier un tableau qui contient des chaînes, des nombres et des nombres sous forme de chaînes (ex. "1", "2"). Je veux trier ce tableau de sorte que le tableau trié contienne d'abord des nombres, puis des chaînes qui contiennent un nombre et enfin des chaînes.

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

J'ai aussi essayé

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
18
Komal Bansal

Il semble que vous ayez fait la plupart du travail lors de votre deuxième tentative. Tout ce que j'ai fait ici est utilisé Array.concat pour joindre les résultats triés de number et char ensemble.

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)
4
ksav

Le plus court est probablement:

 arr.sort((a, b) => ((typeof b === "number") - (typeof a === "number")) || (a > b ? 1 : -1));
20
Jonas Wilms

Vous pouvez d'abord trier les entiers, puis les non-entiers en utilisant .filter() pour séparer les deux types de données.

Voir l'exemple de travail ci-dessous (lire les commentaires du code pour une explication):

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"]
10
Nick Parsons

Je voulais aller un peu plus loin et éviter de boucler plusieurs fois le tableau pour une complexité réduite et donc des performances accrues.

Vous pouvez faire une fonction de tri personnalisée où vous calculez des valeurs de chaîne en fonction de chaque valeur de caractère charCode et les additionnez ainsi que les autres nombres de poignées tels qu'ils sont.

Dans cet exemple de code, j'ai ensuite créé des valeurs de chaîne d'une puissance de 5, pour garantir que les valeurs de chaîne sont supérieures aux valeurs numériques. Cela pourrait être modifié en fonction du cas d'utilisation et du type de données que vous manipulez.

L'inconvénient de cette approche est que les performances sont affectées en fonction de la longueur des chaînes que vous manipulez donc soyez également conscient de cela.

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"]
2
Jimi Pajala

Vous voilà!

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

const numbers = arr.filter(i => typeof i === 'number');
const numerics = arr.filter(i => typeof i === 'string' && !isNaN(i));
const strings = arr.filter(i => typeof i === 'string' && isNaN(i));

numbers.sort();
numerics.sort();
strings.sort()

const result = [].concat(numbers, numerics, strings)

console.log(result)

Ma stratégie consistait d'abord à trouver les trois morceaux (nombres, chiffres et chaînes), puis à les concaténer.

2
Nurbol Alpysbayev

Essayez d'utiliser ceci:

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);

Cela crée trois tableaux, un pour les nombres, un pour les chaînes contenant des nombres et un pour les chaînes. Il trie chaque élément dans le tableau approprié, puis les concatène finalement tous ensemble dans le bon ordre.

2
Jack Bashford

Nous pouvons utiliser la fonction localeCompare à l'intérieur de la fonction sort pour trier le tableau comme

var items = [3, 'rob', 'peter', 43, 0, -222];
console.log(items.sort((a, b) => {
  return a.toString().localeCompare(b.toString());
}));
1
Saksham

Vous pouvez quand même utiliser la méthode Array .sort ().

Il vous suffit de fournir une fonction pour contrôler les critères de tri pour chaque comparaison.

Exemple:

// 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

De toute évidence, la fonctionnalité de la fonction typeClassify() peut être aplatie dans sortCriteria() pour enregistrer un appel de fonction à chaque comparaison. J'ai préféré le mettre de côté pour plus de clarté.

1
bitifet
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);
1
PALLAMOLLA SAI

Essaye ça

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);

Cela utilise la fonction facultative Array.prototype.sort pour trier les éléments dans un tableau. Il doit renvoyer un numéro. Si le nombre> 0, b va en premier. Si le nombre <0, a va en premier. Si c'est 0, leur position reste inchangée.

1
Sergio Tx
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
Niran Manandhar