JavaScript Challenge 2: Word Scrambles
Tags: javascript, challenge, beginners, codenewbie
Published: 2020-10-04 23:27:44

---
canonical_url: https://inspiredwebdev.com/javascript-word-scrambles
---

> This article was originally posted on my [blog](https://inspiredwebdev.com/javascript-word-scrambles). Head over to [inspiredwebdev.com](https://inspiredwebdev.com) for more articles and tutorials. Check out my **JavaScript course** on [Educative](https://www.educative.io/courses/complete-guide-to-modern-javascript?aff=BqmB) to learn everything from ES6 to ES2020.

&nbsp;

In this article we will solve together the *Scrambles* challenge from CodeWars, you can find it at this [link](hthttps://www.codewars.com/kata/55c04b4cc56a697bb0000048/train/javascript).

Let's read the task together:

> Complete the function scramble(str1, str2) that returns true if a portion of str1 characters can be rearranged to match str2, otherwise returns false.
>
> Notes:
> 
> Only lower case letters will be used (a-z). No punctuation or digits will be included.
> Performance needs to be considered
> Input strings s1 and s2 are null-terminated.

The first example we see is this one:

```js
scramble('rkqodlw', 'world') ==> True
```

&nbsp;

## First Solution

My Approach for this challenge will be to iterate over the second string and create a map of how many occurrences of a character appear in it.

Let's start by doing this:

```javascript
const count = {};
    
str2.split('').forEach((c) => {
    count[c] = count[c] ? count[c]+=1 : 1;
})
```

I've instantiated an empty object and then I looped over the `str2` to populate it, using the letters as the keys and increasing a count to know how many times each letter appears.

We need to do this because if we didn't keep track of the count, we could end up with errors where `str1` contains all the letters from `str2` but only once, meaning it does not fulfill the requirement of being able to be re-arranged into `str2`.

Be careful, we cannot call `.forEach` on a `string`, that's why we need to first convert it into an array using `.split('')`.

Now, taking the first example and running the code against it we will get something like this:

```javascript
{ 
    w: 1,
    o: 1,
    r: 1,
    l: 1,
    d: 1 
}
```

What we have to do now is to iterate over the *first* string and for each character of it, check if it appears in this Object we created. If it does, we decrease the count by 1 every time we find it.

```js
str1.split('').forEach((c) => {
    !!count[c] && count[c]--
});
```

Here we are doing the same as before, transforming the `string` into an `Array` and iterating over it. At each iteration, we check if the `count` has a truthy value and in that case, we reduce it by 1. We need to check first, because the second string may contain different letters altogether so it could try accessing the `Object` with properties that don't exist on it.

Once we have done this we need to check if every property of the `count` `Object` is now at 0.

```javascript
return Object.keys(count).every((key) => count[key] === 0);
```

If you don't know how to use `.every` you can read more about in my article about [find and replace in Array](https://inspiredwebdev.com/find-replace-in-array).

Putting everything together, it will look like this:

```javascript
function scramble(str1, str2) {
  
    const count = {};

    str2.split('').forEach((c) => {
        count[c] = count[c] ? count[c]+=1 : 1;
    })

    str1.split('').forEach((c) => {
        count[c] && count[c]--;
    });

    return Object.keys(count).every((key) => count[key] === 0);
}
```

&nbsp;

## Second Solution

Let's try now with a different solution and instead of creating a count map of the letters from `str2` let's do it with `str1`.

```javascript
const count = {};

str1.split('').forEach((c) => {
    count[c] = count[c] ? count[c]+=1 : 1;
})
```

This is the same code as before, I just replaced `str2` with `str1`.

Now, instead of mapping `str1`, reducing the count of each letter from `str2` and then checking the Object if all keys are now of value 0, we can do it a bit differently.

We can loop over `str2` and for each letter, we try to reduce the value in our `count` Object. If the action succeeds for all letters in `str2` it means that `str1` can be rearranged to form `str2`.

Let's see it in action:

```javascript
return str2.split('').every((c) => {
    return count[c]--
});
```

What this code is doing is iterating over each letter of `str2`, reducing the count each time.

We don't care if the count reached 0 or not in this case because `str1` may be much much longer than `str2`.

What we are checking here is that `return count[c]--` will not return `false` either by not finding the corresponding match or by going to a negative value which would mean that `str2` contains more occurrences of that letter than `str1`.

The complete solutions looks like this:

```javascript
function scramble(str1, str2) {
  
    const count = {};

    str1.split('').forEach((c) => {
      count[c] = count[c] ? count[c]+=1 : 1;
    })
  
    return str2.split('').every((c) => {
        return count[c]--
    });
  
}
```

There are many other ways of solving this problem, let me know yours in the comment.

### If you liked this type of content, please let me know in the comments and I'll create more of these.

---

If you want to learn everything about JavaScript from ES6 all the way to ES2020, please check out my book available to read for free on <a target="_blank" href="https://github.com/AlbertoMontalesi/The-complete-guide-to-modern-JavaScript">Github</a>. A course is also on <a target="_blank" href="https://www.educative.io/courses/complete-guide-to-modern-javascript?aff=BqmB"> Educative</a>

[![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/vvr85y9qj36uzo5cutqv.png)](https://www.educative.io/courses/complete-guide-to-modern-javascript?aff=BqmB)

&nbsp;