.every() will stop processing immediately if the method passed to it returns false. The above suggestion does the check in the method passed to .map(), which runs on every element unconditionally. Why not use just .every() so that negative results are found faster?
Here's some injection that will demonstrate:
let counter;
const includesAllWithMap = (s, ...args) => args.map((v) => {
counter += 1;
return s.includes(v);
}).every(Boolean);
const includesAllWithJustEvery = (s, ...args) => args.every((v) => {
counter += 1;
return s.includes(v);
});
counter = 0;
rc = includesAllWithMap('abcdef', 'ab', 'cd', 'ba', 'ef', 'a', 'c');
console.log('result with map =', rc, 'number of comparisons =', counter);
// result with map = false number of comparisons = 6
counter = 0;
rc = includesAllWithJustEvery('abcdef', 'ab', 'cd', 'ba', 'ef', 'a', 'c');
console.log('result with just every =', rc, 'number of comparisons =', counter);
// result with map = false number of comparisons = 3
To make it succinct:
const includesAll = (s, ...args) => args.every(v => s.includes(v));
> includesAll('abcdef', 'ab', 'cd', 'ba', 'ef', 'a', 'c')
// false
> includesAll('abcd', 'a', 'd')
// true
You can make a slight change if you want to provide the substrings in arrays, as the original poster wanted:
const includesAll = (s, ...args) => args.flat().every(v => s.includes(v));
> includesAll('abcdef', ['ab', 'cd', 'ba'], ['ef', 'a', 'c'])
// false
> includesAll('abcd', ['a', 'd'])
// true
> includesAll('abcdef', ['ab', 'abc'], ['de'], ['bcd'])
// true
And if you want both:
const includesAll = (s, ...args) => args.every(v => s.includes(v));
const includesAllinArrays = (s, ...args) => includeAll(s, args.flat());
And if you want an all-in-one (at the sacrifice of some efficiency):
const includesAll = (s, ...args) => args
.map(a => Array.isArray(a) ? a.flat() : [a])
.flat()
.every(v => s.includes(v));
> includesAll('abcdef', 'ab', 'abc', ['d'], ['d', 'e'], 'cd')
// true