# Jewels and Stones

is taken from leetcode

You're given strings J representing the types of stones that are jewels, and S representing the stones you have. Each character in S is a type of stone you have. You want to know how many of the stones you have are also jewels.

The letters in J are guaranteed distinct, and all characters in J and S are letters. Letters are case sensitive, so "a" is considered a different type of stone from "A".

Example 1:

Input: J = "aA", S = "aAAbbbb"

Output: 3

Example 2:

Input: J = "z", S = "ZZ"

Output: 0

Note:

S and J will consist of letters and have length at most 50. The characters in J are distinct.

My functional solution

/**
* @param {string} J
* @param {string} S
* @return {number}
*/
var numJewelsInStones = function(J, S) {
const set = new Set(J);
return [...S].reduce((ac, s) => set.has(s) + ac, 0);
};


My imperative solution:

/**
* @param {string} J
* @param {string} S
* @return {number}
*/
var numJewelsInStones = function(J, S) {
let num = 0;
const set = {};
for (let j = 0; j < J.length; j++) {
set[J[j]] = 1;
}
for (let s = 0; s < S.length; s++) {
num += set[S[s]] || 0;
}
return num;
};


Your code is concise and readable... I didn't have any feedback... it really shows how the functional solution is nicer.

I was curious if it could be done with regular expressions and no iteration, so I played around and got:

const numJewelsInStones = (j,s) => {
const m = s.match(new RegExp([${j}],'g')) return m ? m.length : 0 }  or even numJewelsInStones = (j,s) => s.replace(new RegExp([^${j}],'g'),'').length

• Very clever indeed – thadeuszlay Jun 1 at 18:51

Instead of populating a Set and using .has(), you can use String includes() directly. After that, it's just a matter of filtering the array and taking its length. I'd avoid using regexes unless they actually simplify things.

const countJewels = (J, S) => [...S].filter(n => J.includes(n)).length

console.log(countJewels("aA", "aAaabb"))

Your functions should be const unless you intend to change them. I wouldn't use parameter names like J and S, but I guess those were given by leetcode.

• Includes is slower I think – thadeuszlay Jun 4 at 10:52
• For length 50 it might actually not be. Anyway, the inputs are so short you don't need to care. – JollyJoker Jun 4 at 10:55

here is my proposal: there are fewer cycles, and uses a regex more "simple" for interpreters javascript (I think that the use of the Set consumes more resources)

function numJewelsInStones(J, S)
{
return [...J].reduce((ac, j) => ac + (S.match(RegExp(j)) || []).length, 0)
}

console.log( "'aA', 'aAAbbbb' ==>", numJewelsInStones('aA', 'aAAbbbb') )
console.log( "'z', 'ZZ' ==>", numJewelsInStones('z', 'ZZ') )