我有以下javascript代码产生所需的结果,即返回objectsArray中的第3和第4个对象,因为它们都包含最大距离。但是,我想知道在调用 objectsArray.filter 时是否有办法不必重新键入数组的名称?我不是想偷懒,只是避免冗余和引入拼写错误的可能性。
function meetsMax(obj) {
return obj.distance === Math.max.apply(Math, this.map(function(o) { return o.distance; }));
}
const objectsArray = [{ "distance": 1, "name": "first" }, { "distance": 2, "name": "second" }, { "distance": 3, "name": "third" }, { "distance": 3, "name": "fourth" }];
const objMax = objectsArray.filter(meetsMax, objectsArray);
console.log("objMax:", objMax);
我当然不介意任何其他关于使代码更高效和更高效的指针。
答案 0 :(得分:1)
为什么不使用for循环?它会比你的代码更快。
"use strict";
let start = performance.now();
for (let z = 0; z < 1000; z++) {
function meetsMax(obj) {
return obj.distance === Math.max.apply(Math, this.map(function(o) { return o.distance; }));
}
const objectsArray = [{ "distance": 1, "name": "first" }, { "distance": 2, "name": "second" }, { "distance": 3, "name": "third" }, { "distance": 3, "name": "fourth" }];
const objMax = objectsArray.filter(meetsMax, objectsArray);
}
let fin = performance.now() - start;
console.log(fin); // 3.25ms
&#13;
"use strict";
let start = performance.now();
for (let z = 0; z < 1000; z++) {
let a = [{ "distance": 1, "name": "first" }, { "distance": 2, "name": "second" }, { "distance": 3, "name": "third" }, { "distance": 3, "name": "fourth" }];
let maxDistance = 0;
let result = [];
for (let i = 0, max = a.length; i < max; i++) {
if (a[i].distance > maxDistance) {
maxDistance = a[i].distance;
}
}
for (let i = 0, max = a.length; i < max; i++) {
if (a[i].distance === maxDistance) {
result.push(a[i]);
}
}
}
let fin = performance.now() - start;
console.log(fin); // 1.28ms
&#13;
答案 1 :(得分:1)
JavaScript中的函数调用有一些开销,因此本机代码更有效率和高性能:
var a = [ { "distance": 1, "name": "first" }, { "distance": 2, "name": "second" },
{ "distance": 3, "name": "third" }, { "distance": 3, "name": "fourth" } ]
for (var o = a[0], objMax = [o], m = o.distance, d, i = 1; i < a.length; i++)
if ((d = (o = a[i]).distance) > m) { objMax = [o]; m = d }
else if (d === m) objMax[objMax.length] = o
console.log(JSON.stringify(objMax))
还有更短,效率更低的替代方案:
var a = [ { "distance": 1, "name": "first" }, { "distance": 2, "name": "second" },
{ "distance": 3, "name": "third" }, { "distance": 3, "name": "fourth" } ]
var d, b = []; a.forEach(o => (b[d = o.distance] = b[d] || []).push(o))
console.log(JSON.stringify(b[b.length - 1]))
答案 2 :(得分:0)
.filter
将三个参数传递给数组:当前值,当前值的索引和数组本身。因此,您可以将过滤器功能更改为:
function meetsMax(obj, index, objectsArray) {
return obj.distance === Math.max.apply(Math, objectsArray.map(function(o) { return o.distance; }));
}
并使用
致电.filter
objectsArray.filter(meetsMax);
始终read the documentation您正在使用的功能。
我当然不介意任何其他关于使代码更高效和更高效的指针。
如果你,只计算一次最大距离,而不是每次迭代数组。例如。你可以这样做:
function filterMax(arr, extractor) {
const max = arr.reduce(function(max, item) {
return max < extractor(item) ? extractor(item) : max;
}, extractor(arr[0]));
return arr.filter(function(item) {
return extractor(item) === max;
});
}
并将其命名为
filterMax(objectsArray, function(obj) { return obj.distance; });
function filterMax(arr, extractor) {
const max = arr.reduce(function(max, item) {
return max < extractor(item) ? extractor(item) : max;
}, extractor(arr[0]));
return arr.filter(function(item) {
return extractor(item) === max;
});
}
const objectsArray = [{ "distance": 1, "name": "first" }, { "distance": 2, "name": "second" }, { "distance": 3, "name": "third" }, { "distance": 3, "name": "fourth" }];
console.log(filterMax(objectsArray, function(obj) {
return obj.distance;
}));
答案 3 :(得分:0)
根据MDN's Array.prototype.filter()
,数组名称是this
内部值的可选覆盖。
所以回答原来的问题:
我想知道在调用objectsArray.filter时是否有办法不必重新输入数组的名称?
是的,你可以放心地把它留下来。
var filter = function(x) { if (x > 5) return true; };
var arr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
alert(arr.filter(filter).join(","));
甚至更简单(虽然难以阅读):
alert([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].filter(function(x) { if (x > 5) return true; }));
您特别询问了object
,但是您没有过滤对象,而是过滤对象数组,因此同样适用。
console.log([ {foo: 1}, {foo: 2}, {foo: 3}, {foo: 4}, {foo: 5}, {foo: 6}, {foo: 7}, {foo: 8}, {foo: 9}, {foo: 10}].filter(function(x) { if (x.foo > 5) return true; }));