The includes method
Programs often need to know whether an array holds a value: is this name on the guest list, is this item in the cart? includes(x) answers that. It compares the items with x from the first one on, and returns true as soon as one matches or false if none does.
let colors = ["red", "green", "blue"];
console.log(colors.includes("red"), colors.includes("pink"), colors.includes("Red"));
true false false
Text must match exactly, so "Red" is not "red".
The result is a boolean, so it fits straight into an if. Put ! in front for the opposite: !colors.includes(x) is true when x is missing.
The exercise, step by step
bag holds what is packed for a hike: ["map", "water", "snacks"]. The task is to print one line if water is packed and another if there is no tent.
- Water. Write an
ifwhose condition isbag.includes("water")and printWater is packedinside it. The bag has water, so the print runs. - Tent. Write a second
ifwith the condition!bag.includes("tent")and printPack a tent. The bag has no tent, soincludesgivesfalse, the!turns it intotrue, and the print runs.
let bag: string[] = ["map", "water", "snacks"];
if (bag.includes("water")) {
console.log("Water is packed");
}
if (!bag.includes("tent")) {
console.log("Pack a tent");
}
Water is packed
Pack a tent
Traps
- The name is
includes. Arrays have nocontainsmethod. The compiler reportsProperty 'contains' does not exist on type 'string[]', and if the program runs anyway, the call fails withTypeError: colors.contains is not a function. - Upper and lower case differ. Check the exact text the array holds.
- Objects compare by reference.
[{a: 1}].includes({a: 1})isfalse, because the second object is a different object even though it looks the same. For numbers and strings this doesn't matter. - Parentheses are not needed around the call.
!bag.includes("tent")negates the result of the call. Write the!before the array name, not after.
Another way
indexOf returns the position of the first match, or -1 when there is none, so bag.indexOf("water") is 1 and bag.indexOf("tent") is -1. Use it when you also need the position. For a yes-or-no question, includes reads better.
Using the answer
Because includes checks the items one by one, it stops at the first match. On a short array like a hike bag the cost is invisible. If you ever search a very large array again and again, a Set is built for that job, but for the small lists in this chapter includes is the right tool.
A check like this usually guards another action. For example, add an item only when it is missing:
let packed = ["map"];
if (!packed.includes("tent")) {
packed.push("tent");
}
console.log(packed);
[ 'map', 'tent' ]
Running the same code a second time would leave the array unchanged, because the tent is now there.
Ignoring case
If "Ben" and "ben" should count as the same name, bring both sides to one case first. With guests = ["Ana", "Ben"], guests.includes("ben") is false, while guests.map(g => g.toLowerCase()).includes("ben") is true.
The type matters too. includes compares without converting, so ["1", "2"].includes(1) is false: the string "1" is not the number 1. The compiler also rejects that call, because the argument must be a string.
Key takeaways
arr.includes(x)is aboolean, so use it as anifcondition.!arr.includes(x)means "x is missing".- Strings must match exactly, and objects match only if they are the same object.
