« Previous Tutorial Next Tutorial »

Last week we talked about how you can use Array.includes to determine if an array includes simple values such as strings and numbers. We ran into an issue, though, when we tried this code:

const arrayOfObjs = [{ name: 'Chris' }, { name: 'Sarah'}];
console.log(arrayOfObjs.includes({ name: 'Chris' })); // false

This happens because of how JavaScript handles object instantiation. Basically, you're creating a new object on the second line, not referencing the first one, even though they look identical. You can fix this by having a reference to the object, like this:

const firstObj = { name: 'Chris' };
const secondObj = { name: 'Sarah' };
const newArrayOfObjs = [firstObj, secondObj];
console.log(newArrayOfObjs.includes(firstObj)); // true

That's great, but you're not always going to be able to have defined references for your objects (for example, if they're coming in from a database). So Array.includes isn't always going to work for us. What's the alternative? Well, we can use Array.some. Why? Because it takes a function as a parameter, which allows us a lot more flexibility. Check it out. First we need some data:

const characters = [{ name: 'Gideon' }, { name: 'Harrowhark' }, { name: 'Ianthe' }, { name: 'Dulcinae' }];

By the way, if "magical sword-wielding space necromancers exploring a haunted castle on a ruined planet" sounds like your jam, you should check out Tamsyn Muir's Gideon the Ninth. It's a really fun book!

Anyway, here's a quick-n-dirty object check. We're hard-coding values here, but we'll fix that in a second:

const hasHarrow = characters.some(char => {
  return char.name === 'Harrowhark';
});
console.log(hasHarrow); // true

As you can see, Array.some iterates over every item in the array and passes it to a function of our choice. If ANY execution of that interior function returns true, at any point while Array.some iterates over the array, then Array.some will return true. It might be one in a thousand, or nine hundred and ninety nine in a thousand that return true. Doesn't matter. As long as it's at least one positive, the method will return true.

Hard-coding's gross, though, so let's massage that code a bit so that we can pass the string we're looking for instead. We'll do this by using Array.some inside a container function, like this:

const checkName = (arr, name) => {
  return arr.some(char => char.name === name);
}
console.log(checkName(characters, 'Ianthe')); // true
console.log(checkName(characters, 'Bob')); // false

Now we pass the container function both the array and the character name we want to check for, and presto … we've got a functioning check that doesn't require hard-coded values inside the function.

Now, I'm hoping you see the obvious flaw with all of this: we're just checking a single property of the objects in the array. This isn't a bulletproof strategy at all, as you could easily have an object that has the correct name property but doesn't have the same values in other properties, leading to false positives. In next week's tutorial, we're going to improve this code significantly in order to evaluate more complex objects and make sure we've got a match.

See you then!

As always, you can download example files for each of these tutorials from the JS Quick Hits github repo.

Enjoying these quick hits? You can get them five days early by subscribing to our weekly newsletter.

« Previous Tutorial Next Tutorial »