-2

//Works for an empty array, but with an array with content it says "Cannot set property '0' of undefined"

function countElements(elements) {
   let returnCount = {

   };
 
   for (let i = 0; i < elements.length; i++){
        if (elements[i] !== Object.keys(returnCount)){
            returnCount.elements[i] = 1;
        }
        else if (elements[i] === returnCount.elements[i]){
            returnCount.elements[i] += 1;
        }
    }
    return returnCount;

 
}
ThickNicc
  • 21
  • 2
  • because `returnCount.elements` is `undefined` – Akshay G Jun 13 '21 at 14:44
  • Does this answer your question? [Dynamically access object property using variable](https://stackoverflow.com/questions/4244896/dynamically-access-object-property-using-variable), [dot notation vs. brackets](http://stackoverflow.com/q/4968406/1048572) and [How do I add a property to an object using a variable as the name?](http://stackoverflow.com/q/695050/1048572) – Thomas Jun 13 '21 at 16:29

2 Answers2

2

First of all, returnCount is an object and you are assigning a property identifier as array is not a valid object property and accessing an array index.

returnCount.elements[i] = 1; won't work which is throwing an error returnCount[elements[i]] = 1 would work in your case

also,

if (elements[i] !== Object.keys(returnCount)) will only return false as Object.keys returns an array

Rather than for loop use reduce which is perfect for such kind of problems.

function countElements(elements) {
   return elements.reduce((resultObj,currentElem)=>{
    if(!resultObj[currentElem]){
      resultObj[currentElem]=1;
    }
    else{
    resultObj[currentElem]+=1;
    }
return resultObj;
  },{});
}

const result=countElements(["a","b","p","r","b","p"])
console.log(result)
PRATIK NAIK
  • 489
  • 3
  • 7
  • Thank you so much for your answer! I've got a couple quetions: since Object.keys(returnCount)) gives an array, would if (elements[i] === Object.keys(returnCount)) then be the correct way of approaching it? Also, how is reduce better for this?? – ThickNicc Jun 13 '21 at 15:57
1

Starting from your code you can use the ?? operator that returns its right-hand side operand when its left-hand side operand is null or undefined and rewrite your code like below:

function countElements(elements) {
   let returnCount = {};

   for (let i = 0; i < elements.length; i++) {
       returnCount[elements[i]] = (returnCount[elements[i]] ?? 0) + 1; 
   }

   return returnCount;
}

console.log(countElements(''));
console.log(countElements('a'));
console.log(countElements('ab'));
console.log(countElements('aab'));
dariosicily
  • 4,239
  • 2
  • 11
  • 17
  • Any idea why it is undefined though? Thank you for your answer btw – ThickNicc Jun 13 '21 at 16:00
  • @ThickNicc You are welcome, the issue is that javascript read `returnCount.elements[0] = 1` (your first iteration) as an attempt to assign the value 1 to the `0` property of `returnCount.elements` object that does not exist, this would work if you had `returnCount = { elements : {}}`. This problem is solved using the square bracket notation, you can check for further informations [javascript-property-access-dot-notation-vs-brackets](https://stackoverflow.com/questions/4968406/javascript-property-access-dot-notation-vs-brackets). – dariosicily Jun 13 '21 at 16:33