0

I want to calculate how many times characters appear in a text, and then display the totals for each character. My main problem is the first part.

Here is a snapshot of my code so far:

//define text and characters to be searched for
var theArticle = document.getElementById('theText'),
    docFrag = document.createDocumentFragment(),
    theText = theArticle.innerText,
    characters = {
    a: {
        regExp: /a/g,
        matches: [],
        count: 0
    },
    b: {
        regExp: /b/g,
        matches: [],
        count: 0
    },
    c: {
        regExp: /c/g,
        matches: [],
        count: 0
    }

    etc…
}

for (var key in characters) {
    if (characters.hasOwnProperty(key)) {
        var obj = characters.key;
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop)) {
                matches = theText.match(regExp); // pretty sure my problem is here
                count = matches.length; // and here
            }
        }
    }
}

I would like to loop through all the characters to set the value of matches based on regExp and the value of count based on the length of matches.

The top answer to this question is the closest I've come to solving my problem. Access / process (nested) objects, arrays or JSON

Community
  • 1
  • 1
joel
  • 3
  • 3
  • I can already spot a couple things wrong: 1) There is no need for the check: `if (characters.hasOwnProperty(key))` inside your `for in` loop. 2) You can't access a variable property with dot notation: `var obj = characters.key;` should be `var obj = characters[key];`. 3) Again, no need for the check: `if (obj.hasOwnProperty(prop))`. Correct these things (mainly #2) and it should work as intended. – tenub Mar 06 '14 at 18:57
  • Well, I thought that fixed it, but I guess I got a false positive in the Chrome console. – joel Mar 06 '14 at 19:39

1 Answers1

0

There are several changes that should be made to your code:

  1. There is no need for the check: if (characters.hasOwnProperty(key)) inside your for in loop.
  2. You can't access a variable property with dot notation: var obj = characters.key; should be var obj = characters[key];.
  3. Again, no need for the check: if (obj.hasOwnProperty(prop)).
  4. If you're trying to manipulate the character object properties you need to access the properties on the object, not just by typing the key name.

Correct these things (mainly #2) and it should work as intended.

However, I would completely retool the implementation of your functionality like so:

I would first simply define an array of character strings:

var characters = ['a','b','c','asd'];

Then write a generic function to handle your functionality:

function findCharsInString(array, string) {
    // map a "results" function to each character in the array
    return array.map(function(c) {
        // make a check to ensure we're working with a string that is only one character
        if (typeof c === 'string' && c.length === 1) {
            // create a RegExp from each valid array element
            var matches = string.match(RegExp(c, 'g'));
            // return an anonymous results object for each character
            return {
                matches: matches,
                count: matches.length
            };
        } else { // if there is an invalid element in the array return something
            return 'Invalid array element.';
        }
    });
}

And apply it to your characters array and theText string:

var theText = 'asjdbasccshaskjhsa';
console.log(findCharsInString(characters, theText));

Logs:

[
    {
        matches:
            ["a","a","a","a"],
        count:
            4
    },
    {
        matches:
            ["b"],
        count:
            1
    },
    {
        matches:
            ["c","c"],
        count:
            2
    },
    "Invalid array element."
] 
tenub
  • 3,386
  • 1
  • 16
  • 25
  • this is awesome. thank you. How could you include special characters such as nonbreaking spaces and punctuation? – joel Mar 06 '14 at 22:02
  • I would take a look [here](http://stackoverflow.com/questions/3115150/how-to-escape-regular-expression-special-characters-using-javascript) for escaping `c` in `RegExp(c, 'g')` if you're going beyond basic alphanumerics. You would then need to remove the length check on your characters array as well. – tenub Mar 06 '14 at 22:08
  • again, awesome and thank you. I'm marking this as the answer. The only thing I needed to change was removing the length check (like you suggested), and I added `character: c,` to the top of the anonymous results object to make it a little less anonymous. Also, I can't seem to escape `?`. – joel Mar 06 '14 at 22:29
  • Nevermind on the `?`. If you use `'\\u003f'` then it works just fine. – joel Mar 06 '14 at 22:36