我在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,当我扫描它们以检查时,d
和valsarr
都至少有一些数字,所以第一个代码块正在执行某些操作,至少每一次。
非常感谢任何帮助。
答案 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))
}));