admin管理员组

文章数量:1312889

I am trying to figure out a way to do search while iterating an array. I came across find() method.

Here is the example given:

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5}
];

function findCherries(fruit) { 
    return fruit.name === 'cherries';
}

console.log(inventory.find(findCherries)); 
// { name: 'cherries', quantity: 5 }

I need find a dynamic fruit name, but I can't figure out how to do it. In short, I am trying to do something like:

function findCherries(fruit, fruitName) { 
    return fruit.name === fruitName;
};

inventory.find(findCherries('cherries'))
//"true is not a function"

Is there a way to give find() an argument and find a match base on that argument? If not, what method allows me to search an array of object dynamically?

I am trying to figure out a way to do search while iterating an array. I came across find() method.

Here is the example given:

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5}
];

function findCherries(fruit) { 
    return fruit.name === 'cherries';
}

console.log(inventory.find(findCherries)); 
// { name: 'cherries', quantity: 5 }

I need find a dynamic fruit name, but I can't figure out how to do it. In short, I am trying to do something like:

function findCherries(fruit, fruitName) { 
    return fruit.name === fruitName;
};

inventory.find(findCherries('cherries'))
//"true is not a function"

Is there a way to give find() an argument and find a match base on that argument? If not, what method allows me to search an array of object dynamically?

Share Improve this question asked May 19, 2017 at 23:03 IggyIggy 5,25112 gold badges59 silver badges97 bronze badges 2
  • Search for / read Eloquent JavaScript. The "problem" with the second form is the code eagerly evaluates the function call when it should pass a function-object; this can be solved easily with closures. – user2864740 Commented May 19, 2017 at 23:09
  • 1 Ah, I see! "cherries" is not a function, that's why it didn't work. After reading the ments below, it makes sense to have a callback argument with the dynamic argument stubbed in it. Thanks! – Iggy Commented May 19, 2017 at 23:46
Add a ment  | 

5 Answers 5

Reset to default 5

With a closure (your function must return a function) like this:

function findFruitByName(name) {
    return function(fruit) {
        return fruit.name === name;
    }
}

inventory.find(findFruitByName('cherries'))
// {name: "cherries", quantity: 5}

Try this

// find one
function findFruitByName(name, inventoy) {
  return inventory.find(function(item) {
    return item.name === name;
  });
}

// find all
function findFruitsByName(name, inventory) {
  return inventory.filter(function(item) {
    return item.name === name;
  });
}


let inventory = [
  {name: 'apples', quantity: 2},
  {name: 'bananas', quantity: 0},
  {name: 'cherries', quantity: 5},
  {name: 'cherries', quantity: 88}
];

console.log('One', findFruitByName('cherries', inventory));
console.log('All', findFruitsByName('cherries', inventory));

While a closure is the standard-approach, you could also supply the thisArg to Array.prototype.find and write:

var inventory = [
    {name: 'apples', quantity: 2},
    {name: 'bananas', quantity: 0},
    {name: 'cherries', quantity: 5}
];

function findFruit(fruit) {
    return fruit.name == this;
};

console.log(inventory.find(findFruit, 'cherries'));

I don't remend this approach here as it is a) less obvious and b) this is an Object and needs to be coerced into a primitive string either by non strict equality == or directly converting to String(this), but it can definitely e in handy.

Is there a way to give find() an argument and find a match base on that argument?

Yes. Your first code sample already does that: the argument you are using is a function that looks for cherries.

The argument passed to .find() has to be a function that knows how to do the parison you want. This parison function can be defined anonymously right at the point where you need it:

let result = inventory.find(function(item) {
  return item.name === "cherries";
});

And you can use an arrow function to make the code significantly shorter:

let result = inventory.find(item => item.name === "cherries");

So if the value you are looking for is in some other variable:

let fruit = "cherries";
let result = inventory.find(item => item.name === fruit);
// OR
let result = inventory.find(function(item) {
  return item.name === fruit;
});

(Note that arrow functions aren't supported by IE, but neither is the `.find() method, so...)

You could use thisArg of the find method as argument, like in the code bellow (I used filter, you can use find as well)

var myFind = function(el) {
  return (el.indexOf(this) !== -1); // check if 'el' string contains an 'arg' substring
};

console.log(["abc", "123", "xya", "xyz"]
            .filter(myFind, "a"));         // the argument is "a"
//output: ["abc", "xya"]

本文标签: How to give javascript find() method an argument to searchStack Overflow