4

I need to write a JS function that creates an object from a given string. String characters are object keys. Repeated characters should not be included twice. Values of all keys are zero.

Example: input objFromStr("aaabc") should return {a: 0, b: 0, c: 0}

Here is my solution:

function objFromStr(inStr) {
  let charsArr = inStr.split("");

  let charsObj = {};
  var alreadyInArr = [];

  for (var i = 0; i < charsArr.length; i++) {
    if (!(alreadyInArr.includes(charsArr[i]))) {
      charsObj[charsArr[i]] = 0;
    } else {
      alreadyInArr.push(charsArr[i]);
    }
  }

  return charsObj;
}

This solution works as expected, but I don't understand why. I check chars duplication using alreadyInArr. However when I log my alreadyInArr, it's empty.

So after running this code:

function objFromStr(inStr) {
  let charsArr = inStr.split("");

  console.log("charsArr is:", charsArr);

  let charsObj = {};
  var alreadyInArr = [];

  for (var i = 0; i < charsArr.length; i++) {
    if (!(alreadyInArr.includes(charsArr[i]))) {
      charsObj[charsArr[i]] = 0;
    } else {
      alreadyInArr.push(charsArr[i]);
    }
  }

  console.log("alreadyInArr is:", alreadyInArr);

  return charsObj;
}

console.log(objFromStr("aaabc"));

My output is:

charsArr is: [ 'a', 'a', 'a', 'b', 'c' ]
alreadyInArr is: []
{ a: 0, b: 0, c: 0 }

Can someone explain, why alreadyInArr is empty and yet function still works as expected?

Here's a pen: https://codepen.io/t411tocreate/pen/bYReRj?editors=0012

3
  • 2
    You only add something to alreadyInArr if an item exists in alreadyInArr, but alreadyInArr is empty. Commented Nov 13, 2017 at 17:10
  • 1
    And why does it work? becuase you just overwrite the values.... Commented Nov 13, 2017 at 17:11
  • 2
    You can't define the same key more than once on an object. Your code can repeatedly set obj['a'] = 0, the result obj will still have one key named 'a', where a: 0. Commented Nov 13, 2017 at 17:12

6 Answers 6

3

Your else clause isn't reachable at all since you didn't pushed the element in the right place, you could add a console.log() inside the loop to see that the array still empty through all the iterations.

Instead, the element should be pushed in the if condition like :

for (var i = 0; i < charsArr.length; i++) {
    if (!alreadyInArr.includes(charsArr[i])) {
        charsObj[charsArr[i]] = 0;
        alreadyInArr.push(charsArr[i]);
    }
}

Hope this helps.

function objFromStr(inStr) {
  let charsArr = inStr.split("");

  console.log("charsArr is:", charsArr);

  let charsObj = {};
  var alreadyInArr = [];

  for (var i = 0; i < charsArr.length; i++) {
    if (!alreadyInArr.includes(charsArr[i])) {
      charsObj[charsArr[i]] = 0;
      alreadyInArr.push(charsArr[i]);
    }
  }

  console.log("alreadyInArr is:", alreadyInArr);

  return charsObj;
}

console.log(objFromStr("aaabc"));

Sign up to request clarification or add additional context in comments.

Comments

3

You can shortify your code a bit:

const string = "aabbcc", result = {};

for(const char of string)
  result[char] = 0;

Comments

2

Your else clause means you only push to that array if includes() returns true.

Therefore, you never actually push anything.

Comments

2
 if (!(alreadyInArr.includes(charsArr[i]))) {
      charsObj[charsArr[i]] = 0;
    } else {
      alreadyInArr.push(charsArr[i]);
    }

Your call to alreadyInArr.includes has a ! in front. This reads as so: If NOT(alreadyInarr has a letter CharrsArr[i] within it) then continue:

Which then becomes if the letter is not already in the array then do this.

Since the array is always empty because you don't push anything to it it will always be true and will never step into the else portion

Comments

2

You could spread the carcters and map the objects with the wanted properties.

function objFromStr(inStr) {
    return Object.assign(...Array.from(inStr, k => ({ [k]: 0 })));
}

console.log(objFromStr('aaaabbc'));

1 Comment

I love the solution but it doesn't answer the question. ;P
1

As others have already stated, you are not allowing access to push to the array so you are constantly overwriting your object and assigning 0.

You can cut down your code with the following:

var arr = "aabbc", obj = {};

function objFromStr(inStr) {        
    arr.split("").forEach(function(x){
        obj[x] !== undefined ? obj[x]++ : obj[x] = 1;
    });     
    return obj;
}

console.log(objFromStr(arr));

By doing it this way you don't have to push or track anything in a separate array. It will check the obj to see if the key already exists. If it does it will add 1 to it and if not then it will count it as 1.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.