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
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)
Le plus court est probablement:
arr.sort((a, b) => ((typeof b === "number") - (typeof a === "number")) || (a > b ? 1 : -1));
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"]
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"]
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.
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.
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());
}));
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é.
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);
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.
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)