根据字符串对浮点数进行排序?

时间:2018-02-02 13:08:49

标签: javascript arrays sorting object

我想我终于找到了一个令人恼火的问题的根源。我按产品价格对一系列对象进行排序,有时产品价格不可用,表示为“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值之前列出。

6 个答案:

答案 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")) == trueisNaN(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)

你可以检查属性是否有一个字符串,并获得链式回归值的比较增量。

&#13;
&#13;
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;
&#13;
&#13;

答案 4 :(得分:-1)

你的输出中真的需要N / A吗?将它们过滤掉_.filter(arr, ({price}) => price !== 'N/A'),然后将结果传递给排序函数。排序函数不应该知道N / A我猜,它应该只进行排序。

答案 5 :(得分:-3)

在返回结果之前,您应该先检查isNaN(parseFloat(x))isNaN(parseFloat(y)):如果有NaN,则将其放在最后