在创建数组Javascript之后,Math.Max在数组上返回Nan

时间:2018-02-16 02:46:17

标签: javascript arrays max

我在Javascript中创建了一个应该是所有数字的数组。当我对其使用Math.max时,该函数返回NaN。我很难过。 首先,我知道documentation says Math.max在其中一个参数无法转换为数字时返回NaN,所以我认为这种情况正在发生。我无法理解那是什么。

这里d是一个对象数组。对象是键值对。我想将d数组中每个对象的所有值放入一个新数组中,然后找到最大值。以下是我制作新数组的方法valsarr

var valsarr = [];
d.map(function(row){ 
    Object.keys(row).forEach(function(key) {
        row[key] = Number(row[key]);
        valsarr.push(Number(row[key]));
    });
});

我知道使用Number两次是多余的,但我加上第二个要格外小心。我在其位置尝试了parseInt+并获得了相同的结果。 然后我尝试获取该数组的最大值并打印:

var mymax = Math.max.apply(Math, valsarr)
console.log(mymax);

打印NaN 作为调试过程的一部分,我尝试过滤数组以查找其中的非数字,但我什么都没得到。但是,我对该任务的代码也可能有问题。这是:

function isNotNumber(value) {
    return (typeof(value) !== "number");
}
var badarr = valsarr.filter(isNotNumber);
console.log('Filtered Array\n', badarr); 

它打印一个长度为0的数组。我相信这意味着它在数组中找不到非数字值。

另外两个注释:d中的原始数据包含数千个值。它来自.csvs。因此,我不希望通过所有值来查找不是数字​​的值。我可以很容易地看到原始d对象,valsarr数组中有数字。其次,当我加载我正在使用的其中一个.csvs而不是其他任何一个时,它可以工作。

但是再次,对于任何.csvs,当我扫描它们以检查时,dvalsarr都至少有一些数字,所以第一个代码块正在执行某些操作,至少每一次。

非常感谢任何帮助。

4 个答案:

答案 0 :(得分:0)

也许你可以作弊,并通过在设置值时立即检查来尝试找到行为不当的值:

Object.keys(row).forEach(function(key) {
    row[key] = +row[key];
    valsarr.push(row[key]);
    if (Math.max(row[key]) !== row[key]) {
        console.log(row);
    }
}

然后你可以看到有问题的行...

答案 1 :(得分:0)

您可以使用过滤功能从阵列中删除NaN。

  var valsarr = [];//initialize data in array 
  var result=  valsarr.filter(v => ! isNaN(v));

答案 2 :(得分:0)

Math.max需要多个参数,而不是数组。您可以使用spread(ES7)

Math.max(...[1,2,3,4])

或者您可以使用apply:

Math.max.apply(null,[1,2,3,4])

确保从数组中取出任何不是laxydeveloper建议的数字:

Math.max.apply(null,array.filter(x=>!isNaN(x))

在您的代码中,它看起来像这样:

var d = [
  {p:"hello"},
  {d:2},
  {q:7},
  {other:1,highest:10},
  {q:7}
];
var highest = Math.max.apply(
  null,
  d.map(
    row=>
      Object.keys(row).map(
        key=>
          Number(row[key])
      )
  ).reduce(//flatten array of arrays [[1,2],[2,3]] to [1,2,3,4]
    (all,item)=>all.concat(item),
    []
  ).filter(//take out all that are not numbers
    x=>!isNaN(x)
  )
);
console.log("highest:",highest);

如果您想知道具有最高值的对象的索引和键,您可以这样做:

var d = [
  {p:"hello"},
  {d:2},
  {q:7},
  {other:1,highest:10},
  {q:7}
];
//get highest value,index and the key
const [highestVal,highestKey,highestIndex] = d.map(
  (item,index)=>
    Object.keys(item).reduce(
      (all,key)=>all.concat([[item[key],key,index]]),//val,key,index
      []
    )
).reduce(
  (highest,item)=>{
    return item.reduce(
      (highest,[val,key,index])=>{
        return (val>highest[0])
          ? [val,key,index]
          : highest
      },
      highest
    )
  },
  [-Infinity,undefined,undefined]
);
console.log(
  "highest value:",highestVal,
  "highest object",d[highestIndex],
  "highest key of that object:",highestKey
);

答案 3 :(得分:0)

您应该能够在我的代码中创建的valsArray上运行Math.max()函数,而不会出现任何问题。



// Your code:
/*var valsarr = [];
d.map(function(row){ 
  // This is what you were doing, but you weren't actually returning anything back to the map function, so you weren't creating anything new on the `d` setup, as well as you weren't assigning the return value of the .map() function to anything.
  Object.keys(row).forEach(function(key) {
    row[key] = Number(row[key]);
    valsarr.push(Number(row[key]));
  });
});*/

// Creating a mock set of data for "d", since you didn't provide it.
var d = [
 { a: '1', b: '2', c: '3' },
 { a: '1', b: '2', c: 'test' }, // This should fail.
 { a: '1', b: '2', c: '3' },
 { a: '1', b: '2', c: '3' },
 { a: '1', b: '2', c: '3' }
]

// This is what I think you are trying to do:

// I am doing this concat.apply() method because the Object.values() inside of the .map() method creates a new Array with the values, so we need to concatenate all of them together 
var valsArray = [].concat.apply([], d.map((row) => {
  return Object.values(row)
    .filter((val) => {
      console.log('Trouble-causing row:', isNaN(parseInt(val)), row, val);
      return !isNaN(parseInt(val));
    })
    .map((val) => parseInt(val))
}));