如何将额外的参数传递给 Javascript .filter() 方法中的回调函数?

发布于 2024-12-09 20:29:33 字数 415 浏览 1 评论 0原文

我想将数组中的每个字符串与给定的字符串进行比较。我当前的实现是:

function startsWith(element) {
    return element.indexOf(wordToCompare) === 0;
}
addressBook.filter(startsWith);

这个简单的函数可以工作,但只是因为现在 wordToCompare 被设置为全局变量,但我当然想避免这种情况并将其作为参数传递。我的问题是,我不确定如何定义 startsWith() 因此它接受一个额外的参数,因为我不太明白它所采用的默认参数是如何传递的。我已经尝试了所有我能想到的不同方法,但没有一个有效。

如果您还可以解释传递给“内置”回调函数的参数(抱歉,我不知道更好的术语)如何工作,那就太好了

I want to compare each string in an Array with a given string. My current implementation is:

function startsWith(element) {
    return element.indexOf(wordToCompare) === 0;
}
addressBook.filter(startsWith);

This simple function works, but only because right now wordToCompare is being set as a global variable, but of course I want to avoid this and pass it as a parameter. My problem is that I am not sure how to define startsWith() so it accepts one extra parameter, because I dont really understand how the default parameters it takes are passed. I've tried all the different ways I can think of and none of them work.

If you could also explain how the passed parameters to 'built in' callback functions (sorry, I dont know of a better term for these) work that would be great

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

往昔成烟 2024-12-16 20:29:33

startsWith 接受要比较的单词并返回一个函数,然后将其用作过滤器/回调函数:

function startsWith(wordToCompare) {
    return function(element) {
        return element.indexOf(wordToCompare) === 0;
    }
}

addressBook.filter(startsWith(wordToCompare));

另一种选择是使用 Function.prototype.bind [MDN](仅在支持 ECMAScript 5 的浏览器中可用,请点击旧版浏览器的垫片链接)并“修复”第一个参数:

function startsWith(wordToCompare, element) {
    return element.indexOf(wordToCompare) === 0;
}

addressBook.filter(startsWith.bind(this, wordToCompare));

我不太明白它的默认参数是如何传递的

它没有什么特别的。在某些时候,filter 只是调用回调并传递数组的当前元素。所以它是一个调用另一个函数的函数,在本例中是您作为参数传递的回调。

下面是一个类似函数的示例:

function filter(array, callback) {
    var result = [];
    for(var i = 0, l = array.length; i < l; i++) {
        if(callback(array[i])) {  // here callback is called with the current element
            result.push(array[i]);
        }
    }
    return result;
}

Make startsWith accept the word to compare against and return a function which will then be used as filter/callback function:

function startsWith(wordToCompare) {
    return function(element) {
        return element.indexOf(wordToCompare) === 0;
    }
}

addressBook.filter(startsWith(wordToCompare));

Another option would be to use Function.prototype.bind [MDN] (only available in browser supporting ECMAScript 5, follow a link for a shim for older browsers) and "fix" the first argument:

function startsWith(wordToCompare, element) {
    return element.indexOf(wordToCompare) === 0;
}

addressBook.filter(startsWith.bind(this, wordToCompare));

I dont really understand how the default parameters it takes are passed

There is nothing special about it. At some point, filter just calls the callback and passes the current element of the array. So it's a function calling another function, in this case the callback you pass as argument.

Here is an example of a similar function:

function filter(array, callback) {
    var result = [];
    for(var i = 0, l = array.length; i < l; i++) {
        if(callback(array[i])) {  // here callback is called with the current element
            result.push(array[i]);
        }
    }
    return result;
}
又爬满兰若 2024-12-16 20:29:33

过滤器的第二个参数将在回调内部设置this

arr.filter(callback[, thisArg])

所以你可以这样做:

function startsWith(element) {
    return element.indexOf(this) === 0;
}
addressBook.filter(startsWith, wordToCompare);

The second parameter of filter will set this inside of the callback.

arr.filter(callback[, thisArg])

So you could do something like:

function startsWith(element) {
    return element.indexOf(this) === 0;
}
addressBook.filter(startsWith, wordToCompare);
乖乖公主 2024-12-16 20:29:33

对于那些寻找使用箭头函数的 ES6 替代方案的人,您可以执行以下操作。

let startsWith = wordToCompare => (element, index, array) => {
  return element.indexOf(wordToCompare) === 0;
}

// where word would be your argument
let result = addressBook.filter(startsWith("word"));

使用包括更新版本:

const startsWith = wordToCompare => (element, index, array) => {
  return element.includes(wordToCompare);
}

For those looking for an ES6 alternative using arrow functions, you can do the following.

let startsWith = wordToCompare => (element, index, array) => {
  return element.indexOf(wordToCompare) === 0;
}

// where word would be your argument
let result = addressBook.filter(startsWith("word"));

Updated version using includes:

const startsWith = wordToCompare => (element, index, array) => {
  return element.includes(wordToCompare);
}
巾帼英雄 2024-12-16 20:29:33
function startsWith(element, wordToCompare) {
    return element.indexOf(wordToCompare) === 0;
}

// ...
var word = "SOMETHING";

addressBook.filter(function(element){
    return startsWith(element, word);
});
function startsWith(element, wordToCompare) {
    return element.indexOf(wordToCompare) === 0;
}

// ...
var word = "SOMETHING";

addressBook.filter(function(element){
    return startsWith(element, word);
});
我最亲爱的 2024-12-16 20:29:33

您可以在过滤器内使用箭头函数,如下所示:

result = addressBook.filter(element => element.indexOf(wordToCompare) === 0);

箭头函数在 MDN 上

与函数表达式相比,箭头函数表达式的语法更短,并且在词法上绑定 this 值(不绑定自己的 this、arguments、super 或 new.target)。箭头函数始终是匿名的。这些函数表达式最适合非方法函数,并且不能用作构造函数。

You can use the arrow function inside a filter, like this:

result = addressBook.filter(element => element.indexOf(wordToCompare) === 0);

Arrow functions on MDN

An arrow function expression has a shorter syntax compared to function expressions and lexically binds the this value (does not bind its own this, arguments, super, or new.target). Arrow functions are always anonymous. These function expressions are best suited for non-method functions and they can not be used as constructors.

知你几分 2024-12-16 20:29:33

对于任何想知道为什么他们的胖箭头函数忽略 [, thisArg] 的人,例如为什么

["DOG", "CAT", "DOG"].filter(animal =>animal == =这个,“狗”)
返回 []

这是因为这些箭头函数中的 this 在创建函数时被绑定,并在更广泛的范围内设置为 this 的值范围,因此 thisArg 参数被忽略。我通过在父作用域中声明一个新变量很容易地解决了这个问题:

let bestPet = "DOG";
["狗", "猫", "狗"].filter(动物 => 动物 === bestPet);
=> ["DOG", "DOG"]

以下是更多阅读内容的链接:
https://developer.mozilla.org/ en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this

For anyone wondering why their fat arrow function is ignoring [, thisArg], e.g. why

["DOG", "CAT", "DOG"].filter(animal => animal === this, "DOG")
returns []

it's because this inside those arrow functions are bound when the function is created and are set to the value of this in the broader encompassing scope, so the thisArg argument is ignored. I got around this pretty easily by declaring a new variable in a parent scope:

let bestPet = "DOG";
["DOG", "CAT", "DOG"].filter(animal => animal === bestPet);
=> ["DOG", "DOG"]

Here is a link to some more reading:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#No_separate_this

氛圍 2024-12-16 20:29:33

基于 oddRaven 答案

https://developer.mozilla.org/en -US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

我用两种不同的方式做到了。
1)使用函数方式。
2)采用内联方式。

//Here  is sample codes : 

var templateList   = [
{ name: "name1", index: 1, dimension: 1 }  ,
{ name: "name2", index: 2, dimension: 1 }  ,
{ name: "name3", index: 3, dimension: 2 }  ];


//Method 1) using function : 

function getDimension1(obj) {
                if (obj.dimension === 1) // This is hardcoded . 
                    return true;
                else return false;
            } 

var tl = templateList.filter(getDimension1); // it will return 2 results. 1st and 2nd objects. 
console.log(tl) ;

//Method 2) using inline way 
var tl3 = templateList.filter(element => element.index === 1 || element.dimension === 2  ); 
// it will return 1st and 3rd objects 
console.log(tl3) ;

based on oddRaven answer
and
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

i did it 2 different way .
1) using function way .
2) using inline way .

//Here  is sample codes : 

var templateList   = [
{ name: "name1", index: 1, dimension: 1 }  ,
{ name: "name2", index: 2, dimension: 1 }  ,
{ name: "name3", index: 3, dimension: 2 }  ];


//Method 1) using function : 

function getDimension1(obj) {
                if (obj.dimension === 1) // This is hardcoded . 
                    return true;
                else return false;
            } 

var tl = templateList.filter(getDimension1); // it will return 2 results. 1st and 2nd objects. 
console.log(tl) ;

//Method 2) using inline way 
var tl3 = templateList.filter(element => element.index === 1 || element.dimension === 2  ); 
// it will return 1st and 3rd objects 
console.log(tl3) ;

悍妇囚夫 2024-12-16 20:29:33

有一种简单的方法可以使用过滤器功能,访问所有参数,并且不会使其过于复杂。

除非回调的 thisArg 设置为另一个作用域,否则过滤器不会创建自己的作用域,并且我们可以访问当前作用域内的参数。我们可以设置“this”来定义不同的范围,以便在需要时访问其他值,但默认情况下它被设置为调用它的范围。您可以看到这个用于 Angular 范围 在此堆栈中

使用indexOf违背了过滤器的目的,并增加了更多的开销。 Filter 已经遍历了数组,那么为什么我们需要再次遍历它呢?我们可以把它变成一个简单的 纯函数

这是 React 类方法中的一个用例场景,其中状态有一个名为 items 的数组,通过使用过滤器,我们可以检查现有状态:

checkList = (item) => {  // we can access this param and globals within filter
  var result = this.state.filter(value => value === item); // returns array of matching items

  result.length ? return `${item} exists` : this.setState({
    items: items.push(item) // bad practice, but to keep it light
  });
}

There is an easy way to use the filter function, access all params, and not over complicate it.

Unless the callback's thisArg is set to another scope filter does not create its own scope, and we can access params within the current scope. We can set 'this' to define a different scope in order to access other values if needed, but by default it is set to the scope it's called from. You can see this being used for Angular scopes in this stack.

Using indexOf is defeating the purpose of filter, and adding more overhead. Filter is already going through the array, so why do we need to iterate through it again? We can instead make it a simple pure function.

Here's a use-case scenario within a React class method where the state has an array called items, and by using filter we can check the existing state:

checkList = (item) => {  // we can access this param and globals within filter
  var result = this.state.filter(value => value === item); // returns array of matching items

  result.length ? return `${item} exists` : this.setState({
    items: items.push(item) // bad practice, but to keep it light
  });
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文