0

I created an array from letters of a large string. Now I want to create an object which says how many times that letter is repeated in the array, but I can`t find a solution, please help me out a little.

This is what I done so far:

var str = "Lorem, ipsum dolor sit amet consectetur adipisicing elit. Illo commodi sint fuga autem nobis atque possimus";
var arr = str.split("");

arr.forEach(function(e, i) {
  if (e === " ") {
    //var index = arr.indexOf(e);
    arr.splice(i, 1);
  }
});

var obj = {};
var counter = 0;

arr.forEach(function(e, i) {
  obj[e] = 1;
});

arr2 = Object.keys(obj);
var counter = 0;

for (let c = 0; c < arr.length; c++) {
  for (let b = 0; b < arr2.length; b++) {
    if (arr2[b] == arr[c]) { // to find coincidences
      count++;
      // I'm lost here ..
    }
  }
}
3
  • Your first forEach loop won't work correctly. Use arr.filter instead. Commented Mar 6, 2019 at 23:33
  • Or just ignore spaces in the second forEach loop. Commented Mar 6, 2019 at 23:34
  • Possible duplicate of Count appearance of each character Commented Mar 6, 2019 at 23:37

3 Answers 3

3

You need to increment the counter for each letter, not just set it to 1.

There's no need for the for loop at the end, or the counter variable. obj contains the counts that you want.

var str =
  "Lorem, ipsum dolor sit amet consectetur adipisicing elit. Illo commodi sint fuga autem nobis atque possimus";

var arr = str.split("");

arr = arr.filter(e => e != " ");

var obj = {};

arr.forEach(function(e) {
  if (e in obj) {
    obj[e]++;
  } else {
    obj[e] = 1;
  }
  // Could also be obj[e] = (obj[e] || 0) + 1
});

console.log(obj);

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

3 Comments

instead of looping twice (filter and than forEach) just to remove whitespaces, a simple delete obj[' '] would do the job
Yeah, or just if (e != " ") in the second loop. Lots of ways to skin the cat.
Also, I know e represents a single character - not present in an Object prototype, but it's too easy for a beginner to remember this tricky in operator and get used to it, and one day stumble upon "valueOf" in {} === true. It's longer but definitely good to know Object.prototype.hasOwnProperty.call(obj, "prop")
0

As a fan of regex I'd propose a more short solution:

const str = 'Lorem, ipsum dolor sit amet consectetur adipisicing elit. Illo commodi sint fuga autem nobis atque possimus';

const result = {};

Array.prototype.forEach.call(str.replace(/[^\w]/g, ''), letter => {
    if (letter in result) return;
    result[letter] = str.match(new RegExp(letter, 'g')).length;
});

console.log(result);

You can change regex i flag in order to turn on/off case sensitivity.

2 Comments

You can use \W instead of [^\w]... but why use W at all, it's the same as [^a-zA-Z0-9_] which in this multilingual UTF-8 world is something you should avoid even suggesting, unless you're not regexing phrases but some strict properties or data names.
Thank you for the recommendation, I appreciate
0

Using Array.from() MDN and Array.prototype.reduce MDN :

const str = "Lorem, ipsum dolor sit amet consectetur adipisicing elit. Illo commodi sint fuga autem nobis atque possimus";

const obj = Array.from(str).reduce((ob, c) => {
  ob[c] = ++ob[c] || 1;
  return ob;
}, {});

delete obj[' ']; // If needed remove data for whitespaces
console.log( obj )


  • Array.from(String) will convert a String to Array.
  • No need to remove whitespaces, you can do that later using Object delete
  • reduce will iterate over the array "reducing" it to an Object {}
  • The inner logic ob[c] = ++ob[c] || 1; just instantiates the property with the value 1, otherwise it increments it.

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.