0

So you have two arrays. Search the second array and count how many times each word from the first array occurs in the second one. Display a scrollable list of all the words from the second array and their counts from the first array. I don't want to show only the duplicate values so an intersection function wouldn't help .Use only javascript.

Ex:

listOne = [Pat, cat, hat, Tat, bat, rat];
listTwo = [Pat, mat, sat, rat, cat, Tat, Pat];

And the output would be as follows:

Pat: 2
mat: 0
sat: 0
rat: 1
cat: 1
Tat: 1

I have tried multiple ways and the closest I came up with is this:

function findFreq(listOne, listTwo, concatList) {
  var a = [], b = [], lookup = {}, prev;

  for(var j = 0; j < listTwo.length; j++) {
      lookup[listTwo[j]] = listTwo[j];
  }

  for (var i = 0; i < concatList.length; i++ ) {
      if (concatList[i] !== prev) {
          a.push(lookup[concatList[i]]);
          b.push(0);
      } else {
          b[b.length - 1]++;
      }
      prev = concatList[i];
  }

      return [a, b];          
  }

var result = findFreq(listOne, listTwo, concatList);
alert('[' + result[0] + ']<br />[' + result[1] + ']');

As you can see I thought concating the two arrays would be easiest because all of the examples I found of counting the occurrence of elements only dealt with a single array. In fact I took the code from here and tried modifying it to fit my needs.

The problem is the output gives me empty or extra elements.

[Pat,Tat,,cat,,mat,rat,sat]
[2,1,0,1,0,0,1,0]

So the answer is wrong and so is the formatting. I'm probably over complicating this. It is probably easier to compare the two arrays directly, but I just can't figure it out. Any help would be appreciated.

Note: For my program the two arrays I'm using actually come from user specified files that I just use the split() function on. That's why my naming conventions are strange.

Community
  • 1
  • 1
poniboy4
  • 19
  • 5
  • 3
    Possible duplicate of [Simplest code for array intersection in javascript](http://stackoverflow.com/questions/1885557/simplest-code-for-array-intersection-in-javascript) – Matías Fidemraizer Jan 27 '16 at 22:35
  • Your definition isn't clear. Which of the 2 arrays define the words to look for and which the words to count? – Amit Jan 27 '16 at 22:40
  • Search for words in `listTwo` that match any word from `listOne`. Count the number of times those matched words appear in `listTwo`. Does that make more sense? – poniboy4 Jan 27 '16 at 22:49
  • @MatíasFidemraizer, the "duplicate" question doesn't ask for counts of each word, so its answers don't solve _this_ question. – Simon MᶜKenzie Jan 28 '16 at 04:25

5 Answers5

2

Just loop over both arrays. Something like this should work:

listOne = ["Pat", "cat", "hat", "Tat", "bat", "rat"];
listTwo = ["Pat", "mat", "sat", "rat", "cat", "Tat", "Pat"];


for(var i = 0; i < listOne.length; i++) {
    matches = 0;
    for(var j = 0; j < listTwo.length; j++) {
    if(listOne[i] == listTwo[j]) {
        matches++;
    }
  }
  console.log(listOne[i] + ' has '+ matches+ ' occurance(s)')
}

You can see it working here: https://jsfiddle.net/igor_9000/9n883kse/

Hope that helps!

Adam Konieska
  • 2,805
  • 3
  • 14
  • 27
0
var listOne = 'pat, cat, hat, tat, bat, rat'.split(', ');
var listTwo = 'pat, mat, sat, rat, cat, tat, pat'.split(', ');

// “Count how many times each word from the first array occurs in the second one.”
var results = listOne
  .reduce(function(prev, current) {
    if(!prev[current]) {
      prev[current] = (prev[current] || 0) 
        + listTwo.filter(function(item) { return current === item; }).length;
    }
    return prev;
  }, {});

Returns

{
  "pat": 2,
  "cat": 1,
  "hat": 0,
  "tat": 1,
  "bat": 0,
  "rat": 1
}

Then you could build HTML as a string, for example,

var htmlStr = Object.keys(results)
  .map(function(key) {
    return '<tr><td>'+key+'</td><td>'+results[key]+'</td></tr>';
  })
  .join('\r');

which would yield

'<tr><td>pat</td><td>2</td></tr>
<tr><td>cat</td><td>1</td></tr>
<tr><td>hat</td><td>0</td></tr>
<tr><td>tat</td><td>1</td></tr>
<tr><td>bat</td><td>0</td></tr>
<tr><td>rat</td><td>1</td></tr>'

(I’ve been fast and loose with my line breaks, but you get the idea.)

Justin Makeig
  • 2,097
  • 15
  • 29
  • 1
    This counts the total number of occurrences across both subjects, not the number of times the subject from the first list is matched in the second list. – Adam Konieska Jan 27 '16 at 22:42
  • @JustinMakeig This is something that I haven't been able to figure out in Javascript. In order to get the value of a return statement, I would just have to call the function that the code is located in, correct? But something like `document.getElementById("textarea").innerHTML = function()` gives me undefined. What exactly am I supposed to call in order to get the returns you defined? – poniboy4 Jan 27 '16 at 23:30
  • `var results = listOne.reduce(…` will put the output of the reducer into the variable `results`. If you’re turning that into HTML you’ll need to serialize it appropriately. I've updated my answer above to show an example of building rows of a table from the result. – Justin Makeig Jan 28 '16 at 00:24
0

Using Array.prototype.map() to create array of counts, Array.prototype.reduce() to do counting

listOne = ["Pat", "cat", "hat", "Tat", "bat", "rat"];
listTwo = ["Pat", "mat", "sat", "rat", "cat", "Tat", "Pat"];

var res = listOne.map(function(word) {
  return listTwo.reduce(function(count, test) {
    return word === test ? ++count : count;
  }, 0);
});


document.getElementById('pre').innerHTML =JSON.stringify(res)
console.log(res)//[2,1,0,1,0,1]
<pre id="pre"></pre>
charlietfl
  • 170,828
  • 13
  • 121
  • 150
0

You can create a cycle for the first list and compare all the elements of the second list to each element of the first list to see if they exist and if so, how often repeated.

var listOne = ["Pat", "cat", "hat", "Tat", "bat", "rat"];
var listTwo = ["Pat", "mat", "sat", "rat", "cat", "Tat", "Pat"];    

function findFreq(listOne, listTwo) {
    var a = [], b = [], flag = false, cache = 0;
    for(var i=0; i<listOne.length; i++){
        var temp = listOne[i];
        for(var j=0; j<listTwo.length; j++){
            if(temp === listTwo[j]){
                cache++;
            }
        }
        if(cache!=0){
            a.push(temp);
            b.push(cache);
            cache=0;
        }
    }
    return [a,b];          
}
var result = findFreq(listOne, listTwo);
    for(var k=0; k<result[0].length; k++){
    console.log(result[0][k] + ': ' + result[1][k]);
}
dexhering
  • 422
  • 3
  • 13
0

take a further look at the documentation:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

function myCounter(listOne, listTwo) {
    return [listOne, listTwo].reduce(function(a, b) {
      return a.concat(b);
    }, []).reduce( (countWords, word) => {  
        countWords[word] = ++countWords[word] || 0;     
        return countWords;
    }, {}); 
}

var listOne = ["Pat", "cat", "hat", "Tat", "bat", "rat"];
var listTwo = ["Pat", "mat", "sat", "rat", "cat", "Tat", "Pat"];

console.log(myCounter(listOne, listTwo));

Maybe it helps you!

Pablo Souza
  • 61
  • 1
  • 3