我想我终于找到了一个令人恼火的问题的根源。我按产品价格对一系列对象进行排序,有时产品价格不可用,表示为“N / A”。我期待“N / A”的所有值都放在总排序顺序的最后......但它不是那样的。它似乎有点工作,所有价格首先列出,然后价格和N / A散布在排序的底部。如何/我该怎么做才能解决这个问题?
var arr = [
{id:0,vendor:'ACompany',price:'10.82'},
{id:1,vendor:'ZCompany',price:'10.00'},
{id:2,vendor:'LCompany',price:'9.82'},
{id:3,vendor:'DCompany',price:'N/A'},
{id:4,vendor:'WCompany',price:'11.82'},
{id:5,vendor:'RCompany',price:'N/A'},
{id:6,vendor:'HCompany',price:'10.83'},
{id:7,vendor:'MCompany',price:'10.72'},
{id:8,vendor:'XCompany',price:'9.92'},
{id:9,vendor:'ICompany',price:'N/A'},
{id:10,vendor:'GCompany',price:'10.82'},
] ;
function sortArr(key) {
arr.sort(function(a,b) {
var x = a[key]; var y = b[key] ;
if (key == "vendor") {
return ((x<y) ? -1 : ((x > y) ? 1: 0)) ;
} else {
return parseFloat(x) - parseFloat(y) ;
}
})
}
sortArr('price') ; // when sorting by 'vendor', it works fine.
for (x=0;x<arr.length;x++) {
console.log(arr[x].vendor+ ": " +arr[x].price) ;
}
排序输出为:
LCompany: 9.82
XCompany: 9.92
ZCompany: 10.00
MCompany: 10.72
ACompany: 10.82
GCompany: 10.82
DCompany: N/A
ICompany: N/A
HCompany: 10.83
WCompany: 11.82
RCompany: N/A
而且我知道我不能尝试将价格解析为字符串,'N / A将是最后一个,但$ 10值将在$ 9值之前列出。
答案 0 :(得分:3)
您可以先按NaN
值,然后按价格值对其进行排序。
var arr = [{id:0,vendor:'ACompany',price:'10.82'},{id:1,vendor:'ZCompany',price:'10.00'},{id:2,vendor:'LCompany',price:'9.82'},{id:3,vendor:'DCompany',price:'N/A'},{id:4,vendor:'WCompany',price:'11.82'},{id:5,vendor:'RCompany',price:'N/A'},{id:6,vendor:'HCompany',price:'10.83'},{id:7,vendor:'MCompany',price:'10.72'},{id:8,vendor:'XCompany',price:'9.92'},{id:9,vendor:'ICompany',price:'N/A'},{id:10,vendor:'GCompany',price:'10.82'}];
arr.sort((a, b) => {
let aN = +a.price, bN = +b.price;
return !isNaN(bN) - !isNaN(aN) || aN - bN
})
console.log(arr)
答案 1 :(得分:2)
您的解决方案很接近,但需要处理非数字输入作为特殊例外。您可以按如下方式检测字符串是否为非数字:isNaN(parseFloat("N/A")) == true
,isNaN(parseFloat("3.0")) == false
。
问题是因为NaN有没有排序。 NaN&lt; NaN == false,NaN> NaN == false,NaN == NaN == false。
因此,在您决定使用代码中的parseFloat(x) - parseFloat(y)
进行数字排序之前,请检查该条件并使用您选择的其他顺序。
var arr = [
{id:0,vendor:'ACompany',price:'10.82'},
{id:1,vendor:'ZCompany',price:'10.00'},
{id:2,vendor:'LCompany',price:'9.82'},
{id:3,vendor:'DCompany',price:'N/A'},
{id:4,vendor:'WCompany',price:'11.82'},
{id:5,vendor:'RCompany',price:'N/A'},
{id:6,vendor:'HCompany',price:'10.83'},
{id:7,vendor:'MCompany',price:'10.72'},
{id:8,vendor:'XCompany',price:'9.92'},
{id:9,vendor:'ICompany',price:'N/A'},
{id:10,vendor:'GCompany',price:'10.82'},
] ;
function sortArr(key) {
arr.sort(function(a,b) {
var x = a[key]; var y = b[key] ;
if (key == "vendor") {
return ((x<y) ? -1 : ((x > y) ? 1: 0)) ;
} else {
return isNaN(+x) ? 1 : isNaN(+y) ? -1 : parseFloat(x) - parseFloat(y) ;
}
})
}
sortArr('price') ; // when sorting by 'vendor', it works fine.
for (x=0;x<arr.length;x++) {
console.log(arr[x].vendor+ ": " +arr[x].price) ;
}
这个解决方案比仅处理'N / A'稍微强一些,因为它也会在底部放置任何非数字输入,但不是按照指定的顺序。
答案 2 :(得分:1)
请尝试使用此自定义排序器。
简而言之,数字价格将在数组顶部排序,所有N / A价格类型将按顺序排列到底部。我建议在这里阅读有关自定义分拣机的信息......
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
var arr = [
{id:0,vendor:'ACompany',price:'10.82'},
{id:1,vendor:'ZCompany',price:'10.00'},
{id:2,vendor:'LCompany',price:'9.82'},
{id:3,vendor:'DCompany',price:'N/A'},
{id:4,vendor:'WCompany',price:'11.82'},
{id:5,vendor:'RCompany',price:'N/A'},
{id:6,vendor:'HCompany',price:'10.83'},
{id:7,vendor:'MCompany',price:'10.72'},
{id:8,vendor:'XCompany',price:'9.92'},
{id:9,vendor:'ICompany',price:'N/A'},
{id:10,vendor:'GCompany',price:'10.82'}
];
arr.sort(function(a, b) {
if (a.price == b.price) return 0;
if (a.price == "N/A") return 1;
if (b.price == "N/A") return -1;
return a.price - b.price;
});
console.log(arr);
答案 3 :(得分:1)
你可以检查属性是否有一个字符串,并获得链式回归值的比较增量。
var array = [{ id: 0, vendor: 'ACompany', price: '10.82' }, { id: 1, vendor: 'ZCompany', price: '10.00' }, { id: 2, vendor: 'LCompany', price: '9.82' }, { id: 3, vendor: 'DCompany', price: 'N/A' }, { id: 4, vendor: 'WCompany', price: '11.82' }, { id: 5, vendor: 'RCompany', price: 'N/A' }, { id: 6, vendor: 'HCompany', price: '10.83' }, { id: 7, vendor: 'MCompany', price: '10.72' }, { id: 8, vendor: 'XCompany', price: '9.92' }, { id: 9, vendor: 'ICompany', price: 'N/A' }, { id: 10, vendor: 'GCompany', price: '10.82' }];
array.sort(function (a, b) {
return (a.price === 'N/A') - (b.price === 'N/A') || a.price - b.price;
});
console.log(array);
&#13;
.as-console-wrapper { max-height: 100% !important; top: 0; }
&#13;
答案 4 :(得分:-1)
你的输出中真的需要N / A吗?将它们过滤掉_.filter(arr, ({price}) => price !== 'N/A')
,然后将结果传递给排序函数。排序函数不应该知道N / A我猜,它应该只进行排序。
答案 5 :(得分:-3)
在返回结果之前,您应该先检查isNaN(parseFloat(x))
和isNaN(parseFloat(y))
:如果有NaN
,则将其放在最后