Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/464.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 有没有一种方法可以让对象过滤器在没有命名引用的情况下传递对象?_Javascript_Arrays_Sorting - Fatal编程技术网

Javascript 有没有一种方法可以让对象过滤器在没有命名引用的情况下传递对象?

Javascript 有没有一种方法可以让对象过滤器在没有命名引用的情况下传递对象?,javascript,arrays,sorting,Javascript,Arrays,Sorting,我有下面的javascript代码,可以生成所需的结果,即返回objectsArray中的第3个和第4个对象,因为它们都包含最大距离。但是,我想知道是否有一种方法可以在调用objectsArray.filter时不必重新键入数组的名称?我不是想偷懒,只是想避免冗余和输入错误的可能性 function meetsMax(obj) { return obj.distance === Math.max.apply(Math, this.map(function(o) { return o.d

我有下面的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);

我当然不介意任何其他的指针来提高代码的效率和性能。

.filter
将三个参数传递给数组:当前值、当前值的索引和数组本身。因此,您可以将过滤器功能更改为:

function meetsMax(obj, index, objectsArray) {

    return obj.distance === Math.max.apply(Math, objectsArray.map(function(o) { return o.distance; }));
}
并使用调用
.filter

 objectsArray.filter(meetsMax);

始终保留您正在使用的函数的名称


我当然不会介意任何其他关于提高代码效率和性能的建议

如果需要,请仅计算一次最大距离,而不是在数组的每次迭代中。例如,你可以做:

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;
    });
}
函数过滤器最大值(arr,提取器){
const max=arr.reduce(函数(最大值,项){
返回最大值<提取器(项目)?提取器(项目):最大值;
},提取器(arr[0]);
返回arr.filter(函数(项){
返回提取器(项目)==最大值;
});
}
const objectsArray=[{“距离”:1,“名称”:“第一”},{“距离”:2,“名称”:“第二”},{“距离”:3,“名称”:“第三”},{“距离”:3,“名称”:“第四”}];
log(filterMax(objectsArray,函数(obj)){
返回目标距离;

}));为什么不使用for循环?它将比你的代码快

“严格使用”;
让start=performance.now();
for(设z=0;z<1000;z++){
函数meetsMax(obj){
return obj.distance===Math.max.apply(Math,this.map(函数(o){return o.distance;}));
}
const objectsArray=[{“距离”:1,“名称”:“第一”},{“距离”:2,“名称”:“第二”},{“距离”:3,“名称”:“第三”},{“距离”:3,“名称”:“第四”}];
const objMax=objectsArray.filter(meetsMax,objectsArray);
}
让fin=performance.now()-start;
控制台日志(fin);//3.25ms
根据,数组名称是对
的内部值的可选覆盖

因此,要回答原来的问题:

我想知道在调用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(","));
或者更简单(尽管更难阅读):

您专门询问了一个
对象
,但您不是在筛选对象,而是在筛选一个对象数组,因此同样适用

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; }));

JavaScript中的函数调用有一些开销,因此本机代码更高效、性能更好:

var a=[{“距离”:1,“名称”:“第一”},{“距离”:2,“名称”:“第二”},
{“距离”:3,“名称”:“第三”},{“距离”:3,“名称”:“第四”}]
对于(var o=a[0],objMax=[o],m=o.distance,d,i=1;im{objMax=[o];m=d}
如果(d==m)objMax[objMax.length]=o,则为else

console.log(JSON.stringify(objMax))
请参阅。
Math.max.apply(Math,this.map(function(o){return o.distance;}))
更简单:
this.reduce((c,i)=>Math.max(c,i))
并在循环之前更好地执行
Math.max(c,i)
,这回答了过滤问题,它没有解决性能问题-当前筛选器非常浪费,目标数组在每次迭代中都映射。一次性减少整个数组的成本要低得多。问题的最后一行询问“如何提高代码的效率和性能”。这是一个非常直截了当的关于性能的问题。这方面的性能非常好(在我的机器上为0.09毫秒),我喜欢它的一般结构。在对几乎所有答案进行性能测试后(截至本文撰写时),我发现第一个性能最好(比下一个最好的大约快30倍)。事实上,写一个“min”版本,性能甚至更好。我希望它和@zhuravlyov的第二个版本差不多。不同浏览器之间的差异可能很大,但另一个很大的优势是,它可以在不支持ES5方法的旧浏览器上工作。@zhuravlyov的第二款和这一款都适用于Chrome、IE II、Edge和Firefox。总体而言,这要快得多。在IE/Edge中,它比Chrome或Firefox快,而另一种方法则非常慢。在Chrome或FF中,这大约快10倍。我将主要在node.js中使用它。
alert([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10].filter(function(x) { if (x > 5) return true; }));
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; }));