文字列、数字、数字を文字列として含む配列を並べ替えようとしています(例: '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
2回目の試行でほとんどの作業を完了したようです。ここで行ったことはすべて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)
最短はおそらく:
arr.sort((a, b) => ((typeof b === "number") - (typeof a === "number")) || (a > b ? 1 : -1));
.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"]
これをもう少し進めて、複雑さを減らしてパフォーマンスを向上させるために、アレイを複数回ループさせないようにしました。
各文字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"]
はい、どうぞ!
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)
私の戦略は、最初に3つのチャンク(数字、数字、文字列)をすべて見つけてから、それらを連結するだけでした。
これを使ってみてください:
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);
これにより、3つの配列が作成されます。1つは数字用、もう1つは数字を含む文字列用、もう1つは文字列用です。各要素を適切な配列にソートし、最後に正しい順序でそれらをすべて連結します。
localeCompare
関数内のsort
関数を利用して、配列を次のようにソートできます。
var items = [3, 'rob', 'peter', 43, 0, -222];
console.log(items.sort((a, b) => {
return a.toString().localeCompare(b.toString());
}));
とにかく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()
にフラット化して、すべての比較で関数呼び出しを保存できます。明確にするために、それを分解することを好みました。
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);
これを試して
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 オプション関数を使用して、1つの配列内の要素をソートします。数値を返す必要があります。数値が0より大きい場合、bが最初になります。数値<0の場合、aが最初になります。 0の場合、それらの位置は変更されません。
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)