Counting unique words in strings

Below I am trying to pass string arrays to a function that adds unique words to an array of words, and if the word is already in the array, to increment the counter of the corresponding element in the array count:

var words = [];
var counts = [];

calculate([a, b]);
calculate([a, c]);

function calculate(result) {
    for (var i = 0; i < result.length; i++) {
        var check = 0;
        for (var j = 0; i < tags.length; i++) {
            if (result[i] == tags[j]) {
                check = 1;
                counts[i] = counts[i] + 20;
            }
        }
        if (check == 0) {
            tags.push(result[i]);
            counts.push(20);
        }
        check = 0;
    }
}

      

However, the output is obtained as follows:

words = a, b count = 2, 1

When I expect it to be: words = a, b, c count = 2,1,1

Thanks for any help in advance

+3


source to share


4 answers


Please check it out: you can check it out at: http://jsfiddle.net/knqz6ftw/

var words = [];
var counts = [];

calculate(['a', 'b']);
calculate(['a', 'c']);
calculate(['a', 'b', 'c']);

function calculate(inputs) {
    for (var i = 0; i < inputs.length; i++) {
    var isExist = false;
    for (var j = 0; j < words.length; j++) {
        if (inputs[i] == words[j]) {
            isExist = true
            counts[i] = counts[i] + 1;
        }
    }
    if (!isExist) {
        words.push(inputs[i]);
        counts.push(1);
    }
    isExist = false;
}
}

console.log(words);
console.log(counts);

      



Output:

["a", "b", "c"] (index):46
[3, 2, 2] 

      

+1


source


Overcoming the problem in methods with good names helps you work out your logic.

Try the following:

<script type="text/javascript">
var words = [];
var counts = [];
calculate(["a", "b"]);
calculate(["a", "c"]);
console.log(words);
console.log(counts);

function calculate(result) {
    for (var i=0; i<result.length; i++) {
        if (array_contains(words, result[i])) {
            counts[result[i]]++;
        } else {
            words.push(result[i]);
            counts[result[i]] = 1;
        }
    }
}

function array_contains(array, value) {
    for (var i=0; i<array.length; i++)
        if (array[i] == value)
            return true;
    return false;
}

</script>

      



Output:

["a", "b", "c"]
[]
  a 2
  b 1
  c 1

+2


source


Several things were wrong, here is the working code:

var words = [];
var counts = [];

calculate(["a", "b"]);
calculate(["a", "c"]);

function calculate(result) {
    for (var i = 0; i < result.length; i++) {
        var check = 0;
        for (var j = 0; j < words.length; j++) {
            if (result[i] == words[j]) {
                check = 1;
                ++counts[j];
            }
        }
        if (check == 0) {
            words.push(result[i]);
            counts.push(1);
        }
        check = 0;
    }
}

      

Jsbin: http://jsbin.com/hawaco/2/edit?js,console

Things I changed:

  • Modified array literal to pass strings instead of variable names: [a,b]

    to["a","b"]

  • Replaced instances of tags

    (presumably the old name) withwords

  • Changed the value from 20 s 1 s
  • Increased value counts[j]

  • Fixed using indexes i

    /j

Things to consider:

  • Maybe it's a dictionary, not a couple of arrays:, {"a":1, "b":2}

    which will simplify the code
  • Pass array names to allow for other accumulators, or combine method and arrays into one object

Simplified:

var seen = {};

count(["a", "b"], seen);
count(["a", "c"], seen);

function count(words, accumulator) {
    for (var i = 0; i < words.length; ++i) {
        if(!accumulator.hasOwnProperty(words[i])) {
          accumulator[words[i]] = 1;
        } else {
          ++accumulator[words[i]];
        }
    }
}

      

Result:

>> seen
[object Object] {
  a: 2,
  b: 1,
  c: 1
}

      

JSBin: http://jsbin.com/halak/1/edit?js,console

+1


source


Here's my solution (using an object):

  const checkWord = (str) => {
    let collection = {};
    // split the string into an array
    let words = str.split(' ');
    words.forEach((word) => {
     collection[word] = word;
   });
   // loop again to check against the array and assign a count
   for (let j = 0; j < words.length; j++) {
     if (words[j] === collection[words[j]]) {
       collection[words[j]] = 0;
     }
     collection[words[j]]++
   }
   console.log(collection);
 };

      

You can also use reduce

:

  const checkWord = (str) => {
  let collection = {};
  let words = str.split(' ');
  words.forEach((word) => {
     collection[word] = word;
   });
  for (var i = 0; i < words.length; i++) {
    if (words[i] === collection[words[i]]) {
      collection[words[i]] = 0;
    }
  }
  let total = words.reduce((occurrences, word) => {
    collection[word]++
    return collection;
}, 0);
    console.log(total);
  };

      

+1


source







All Articles