2

I am writing a script for Google Spreadsheet.

Array 1 have a series of names (more than 50 different names)

John, Pete, Paul, ... Michael

Array 2 is a series of repeated names from those given 50 (more than 10K in total)

Paul, Michael, Pete, John, Paul, Paul, Pete, Michael, Paul, Michael,... Michael

How can I make another Array with the number of occurrences (Array 2) for every given name in Array 1?

Sorting is not possible. Therefore, Array 3 should take into consideration the order of Array 1. In this case, for instance:

1, 2, 3,... 4

I have seen & proved how to make it if order is not important (from Array 2, Array 1 is created with unique names and Array 3 contains their occurrences --> Counting the occurrences of JavaScript array elements), but all my approaches seem to don't work. So far, I have this:

var namesCountArray = [];
namesArray = ss.getRange("CU3:CU" + rows + "").getValues();
namesSerieArray = ss.getRange("DF3:DF" + rows + "").getValues();

for(var i=0; i< namesArray.length; i++) {
    var count = 0;
    for(var i = 0; i < namesSerieArray.length; ++i) {
        if(namesSerieArray[i] == namesArray[i])
            count++;
    }
    namesCountArray.push([count]);
}
ss.getRange("DB3").setValue(namesCountArray);
1
  • do you really need to do this with a script? you may simply use a counta formula or for a more complicated analysis a pivot table? Commented Sep 30, 2014 at 15:46

3 Answers 3

3

You need to use a different variable in the second for loop or take it out all together:

for(var i=0; i< namesArray.length; i++) {
  var count = 0;
  for(var i = 0; i < namesSerieArray.length; ++i){
  if(namesSerieArray[i] == namesArray[i])
    count++;
  }

You're going through and checking each pair 1 with 1, 2 with 2, 3 with 3 only. You should do separate variables if you want to check each index pair (1 with 1, 1 with 2 ...). Ex:

for(var i=0; i< namesArray.length; i++) {
  var count = 0;
  for(var j = 0; j < namesSerieArray.length; j++){
  if(namesSerieArray[i] == namesArray[j])
    count++;
  }
Sign up to request clarification or add additional context in comments.

6 Comments

Good eye. I totally missed that i was used for both loops. The count is being pushed as [count], so that may be an issue too if that wrapping array wasn't wanted.
Right, he may intend for it to be that way. Not sure. However the loop is actually closed. The if statement doesn't use curly braces. :)
Yeah, I noticed that afterwards and deleted my comment because I was being a goof. But yeah, I didn't know exactly what all he wanted so I left it alone. xP
@CharlesB., thx. You was not being goof at all (I red the original msg but couldn't answer until yet). I have to admit my ignorance. Today is my first day using arrays, and one month ago I didn't have any experience, so it's possible that the original code was totally false. @squint, I'm using [count] because Google App Scripts requires it. At least with other Arrays have worked, because without [] it always says Cannot convert Array to Objec. However, as my code is originally buggy, it maybe doesn't need the brackets.
The problem is, however, that I cannot make it work. Do you think it's because Google App Scripts generates 2-Dim Arrays when calling namesArray = ss.getRange("CU3:CU" + rows + "").getValues();? If I print this array in one cell I get something like this [[Pete], [John], [Paul],... [Michael]] instead of ["Pete", "John", "Paul",... "Michael"].
|
3
// names we want to find
var names = ["john", "pete", "paul"];

// target list of names.
// john, pete, paul appear 2x
var target = ["john", "pete", "jack", "cindy", "thomas", "paul", "john", "pete", "paul"];

function finder(search, target) {
    return search.map(function (val) {
        return target.filter(function (e) {
            return val === e;
        }).length;
    });
}

finder(names, target);
// => [2, 2, 2]

Demo: http://jsfiddle.net/austinpray/v14o38ta/

5 Comments

Were jack and cindy the 13th and 14th members of the crew ;)
@RyanWheale haha I don't get it, what do you mean?
Most of these are names of disciples... of which there were 12. Though Michael and Paul are not disciples, I just thought it was funny you didn't stick with the biblical paradigm.
thx @AustinPray it works wonderfully on fiddle, but (like usually) don't in my implementation. Do you think it's because what I comment in the first answer?
@agustin I will edit my answer to make it work. Can you give me a sample "target" array?
3

Walk through the array2 and build an object with every key as a name and the value as the number of its occurences.

e.g.

var array2 = ["Paul", "Michael", "Pete", ... /* 47 more names */ ];
var occurences = {};

for (var i = 0, l = array2.length; i++; i<l) {
   if (occurences[array2[i]] === undefined) {
     occurences[array2[i]] = 1;
   }
   else {
     occurences[array2[i]]++;
   }
}

then walk the first array, check if the name is in the object occurences and push its value in a new array, like so

var array1 = ["Paul", "Michael", "Pete", "John", "Steve", "Bill" ];
var array1Frequency = [];

for (var i = 0, l = array1.length; i++; i<l) {
    array1Frequency.push(occurences[array1[i]] || 0)
}

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.