我有一个带有混合字母数字的Object数组。我需要按大小排序。
var data = [
{size: "40 SHORT", avail: true},
{size: "46 LONG", avail: true},
{size: "42 SHORT", avail: true},
{size: "40 REG", avail: true},
{size: "42 LONG", avail: true},
{size: "42 REG", avail: true},
{size: "44 REG", avail: true},
{size: "44 LONG", avail: true},
{size: "46 REG", avail: true},
{size: "48 REG", avail: true},
{size: "44 SHORT", avail: true},
{size: "38 REG", avail: true},
{size: "40 LONG", avail: true},
{size: "48 LONG", avail: true},
{size: "38 SHORT", avail: true}
]
我需要像这样的输出。
var Output = [
{size: "38 SHORT", avail: true},
{size: "40 SHORT", avail: true},
{size: "42 SHORT", avail: true},
{size: "44 SHORT", avail: true},
{size: "38 REG", avail: true},
{size: "40 REG", avail: true},
{size: "42 REG", avail: true},
{size: "44 REG", avail: true},
{size: "46 REG", avail: true},
{size: "48 REG", avail: true},
{size: "40 LONG", avail: true},
{size: "42 LONG", avail: true},
{size: "44 LONG", avail: true},
{size: "46 LONG", avail: true},
{size: "48 LONG", avail: true}
]
答案 0 :(得分:0)
您需要做的是对字符串进行排序,但作为两个不同的属性。因此,如果你可以在适当的位置创建一个新的排序数组,我会将数组映射到一个包含原始数据的对象数组,另一个属性包含在空格字符上拆分字符串的结果。
然后您需要做的就是首先查看SHORT/REG/LOG
是否匹配,如果是,请对数字进行排序,否则按照为这些单词定义的顺序排序。
var data = [{size: "40 SHORT", avail: true},{size: "46 LONG", avail: true},{size: "42 SHORT", avail: true},{size: "40 REG", avail: true},{size: "42 LONG", avail: true},{size: "42 REG", avail: true},{size: "44 REG", avail: true},{size: "44 LONG", avail: true},{size: "46 REG", avail: true},{size: "48 REG", avail: true},{size: "44 SHORT", avail: true},{size: "38 REG", avail: true},{size: "40 LONG", avail: true},{size: "48 LONG", avail: true},{size: "38 SHORT", avail: true}];
data = data
.map(o => ({orig: o, p: o.size.split(' ')}))
.sort((a, b) =>
a.p[1] === b.p[1] ? a.p[0] - b.p[0] :
a.p[1] === "SHORT" || (a.p[1] === "REG" && b.p[1] === "LONG") ? -1 :
1)
.map(o => o.orig);
console.log(data);
您也可以进行就地排序。我们只需要将结果复制到原始数组中。
无论哪种方式,这里的好处是我们不会在.sort()
回调内的每次迭代中进行字符串拆分和对象创建,这在计算和内存消耗方面会不必要地花费。
这个甚至更清洁,更快。它利用了单词固有的反向字母顺序。它使用排序中每个单词的第一个字母的否定字符代码,因此它完全是数字排序。
var data = [{size: "40 SHORT", avail: true},{size: "46 LONG", avail: true},{size: "42 SHORT", avail: true},{size: "40 REG", avail: true},{size: "42 LONG", avail: true},{size: "42 REG", avail: true},{size: "44 REG", avail: true},{size: "44 LONG", avail: true},{size: "46 REG", avail: true},{size: "48 REG", avail: true},{size: "44 SHORT", avail: true},{size: "38 REG", avail: true},{size: "40 LONG", avail: true},{size: "48 LONG", avail: true},{size: "38 SHORT", avail: true}];
data = data
.map(o => {
let [n,t]=o.size.split(' ');
return {orig:o, n:+n, t:-t.charCodeAt()}
})
.sort((a, b) => a.t - b.t || a.n - b.n)
.map(o => o.orig);
console.log(data);
答案 1 :(得分:0)
这是我的尝试。它不是通用的,但它的想法是分离" size"的字面部分。来自" size"的数字部分并进行顺序比较。
function compare(a, b) {
// obvious equality case, just to skip unnecessary calculations
if(a.size === b.size) {
return 0;
}
// literal comparison: SHORT < REG < LONG
var aL = a.size.replace(/^[\s\d]+/, ''), bL = b.size.replace(/^[\s\d]+/, '');
if((aL == 'SHORT' && bL != 'SHORT') || (aL == 'REG' && bL == 'LONG')) {
return -1;
}
if((aL == 'REG' && bL == 'SHORT') || (aL == 'LONG' && bL != 'LONG')) {
return 1;
}
// numeric comparison: 38 < 40 < 44 etc
var aN = parseInt(a.size, 10), bN = parseInt(b.size, 10);
if (aN < bN) {
return -1;
}
if (aN > bN) {
return 1;
}
return 0;
}
console.log(data.sort(compare));
答案 2 :(得分:-1)
您可以拆分该值并获取给定大小的数值。
var data = [{ size: "40 SHORT", avail: true }, { size: "46 LONG", avail: true }, { size: "42 SHORT", avail: true }, { size: "40 REG", avail: true }, { size: "42 LONG", avail: true }, { size: "42 REG", avail: true }, { size: "44 REG", avail: true }, { size: "44 LONG", avail: true }, { size: "46 REG", avail: true }, { size: "48 REG", avail: true }, { size: "44 SHORT", avail: true }, { size: "38 REG", avail: true }, { size: "40 LONG", avail: true }, { size: "48 LONG", avail: true }, { size: "38 SHORT", avail: true }];
data.sort(function (a, b) {
function getParts(o) {
var array = o.size.split(' ');
return { value: array[0], size: { SHORT: 1, REG: 2, LONG: 3 }[array[1]] };
}
var aa = getParts(a),
bb = getParts(b);
return aa.size - bb.size || aa.value - bb.value;
});
console.log(data)
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;