1
var people = new Array();
function People (name, location, age){
    this.name = name;
    this.location = location;
    this.age = age;
}

I have two other functions to generate the people and load them into a table.

function generatePeople(){}
function loadPeopleIntoTable(){}

I need to basically go through the list of people, take their names and then show the most common first names that appear in that table. That function is simply called commonFirstName().

function commonFirstName(){}

The hint given is "JavaScript objects can be indexed by strings" but I don't understand that 100%. I have already written the code for going through the array and finding the common first name. But I can't call in the peoples array to go through that list - I can only get it to work with a manual created array in commonFirstName(). Why is that?

I can provide some further clarification if needed.


function commonFirstName(){ 
       alert(people[1]); 
       //Rest of code that does the occurrences/name here 
 }

The output for this is simply [object Object].

On the other hand:

function commonFirstName(){
tempArray = ['John Smith', 'Jane Smith', 'John Black'];
//Run through algorithm for finding common name. 
}

Gives an alert output of "Common Name: John. Occurs 2 times"

I had thought if I simply passed the array people through the function such as:

function commonFirstName(people){
alert(people[1]);
}

Should give me something, anything. I'm not expecting just the first name at this point but at least the full name, location and age of element 1 or one of those. It just doesn't run at all, as though the array doesn't exist or is simply empty.

This is my code for everything I have:

    var PEOPLECOUNT = 100;
    var people = new Array();

    function People(name, location, age) {
      this.name = name;
      this.location = location;
      this.age = age;
    }

    function initPage() {
      generateTableRows();
      generatePeople();
    }

    function generateTableRows() {
      var table = document.getElementById("ageTable");
      var tableBody = table.getElementsByTagName("tbody")[0];

      for (var i = 0; i < PEOPLECOUNT; i++) {
        var newRow = document.createElement("tr");

        newRow.setAttribute("id", "ageRow" + i.toString(10));

        var td1 = document.createElement("td");
        var td2 = document.createElement("td");
        var td3 = document.createElement("td");

        td1.setAttribute("class", "dataCell");
        td2.setAttribute("class", "dataCell");
        td3.setAttribute("class", "dataCell");

        newRow.appendChild(td1);
        newRow.appendChild(td2);
        newRow.appendChild(td3);
        tableBody.appendChild(newRow);
      }
    }

    function generatePeople() {
      var firstNames = ["Jack", "Will", "Josh", "Tom", "Sam", "Chloe", "Emily", "Sophie", "Lily", "Olivia"];
      var surnames = ["Smith", "Jones", "Brown", "Taylor", "Johnson", "White"];
      var locationNames = ["Canyonville", "Hailsmere", "Northpath", "Gracemont", "Gainsburgh", "Heathersmith"];

      for (var i = 0; i < PEOPLECOUNT; i++) {
        var name = firstNames[randInt(firstNames.length - 1)] + " " + surnames[randInt(surnames.length - 1)];
        var location = location[randInt(locationNames.length - 1)];
        var age = randInt(100);
        var currentPeople = new People(name, location, age);

        people.push(currentPeople);
      }

      loadPeopleIntoTable();
    }

    function loadPeopleIntoTable() {
      for (var i = 0; i < PEOPLECOUNT; i++) {
        var people = people[i];
        var peopleRow = document.getElementById("ageRow" + i.toString(10));
        var cells = peopleRow.getElementsByTagName("td");

        for (var j = 0; j < cells.length; j++) {
          if (cells[j].hasChildNodes()) {
            cells[j].removeChild(cells[j].childNodes[0]);
          }
        }

        cells[0].appendChild(document.createTextNode(people.name));
        cells[1].appendChild(document.createTextNode(people.location));
        cells[2].appendChild(document.createTextNode(people.age.toString(10)));
      }
    }

function randInt(maxVal) {
                return Math.floor(Math.random() * (maxVal + 1));
            }

    function commonFirstName() {

      var tempArray = [];
      var fName;
      var array = ['John Smith', 'Jane Smith', 'John Black'];
      for (i = 0; i < array.length; i++) {
        fName = array[i].split(' ').slice(0, -1).join(' ');
        tempArray.push(fName);
      }

      var mostCommon;
      var occurences = 0;
      for (j = 0; j < tempArray.length; j++) {
        var tempName = tempArray[j];
        var tempCount = 0;
        for (k = 0; k < tempArray.length; k++) {
          if (tempArray[k] == tempName) {
            tempCount++;
          }
          if (tempCount > occurences) {
            mostCommon = tempName;
            occurences = tempCount;
          }
        }
      }
      alert(mostCommon + " : " + occurences);
    }

Now this works with the array fullNames that is in the function but not for the array of people, which consists of People objects with name, location and age (as shown at the start). I just need that array passed through so I can split the elements -_-

Yamenstein
  • 19
  • 2
  • Please, share your code for going through the array. – Gerardo Furtado Jun 25 '16 at 04:40
  • this.name===this["name"], it's like a hash map in java or a dictionary in other languages – chiliNUT Jun 25 '16 at 04:42
  • Please provide code where you are using the People() method and people[] array. – Jignesh Patel Jun 25 '16 at 04:44
  • 1
    It sounds to me like you need to store the people's names in an object and create a frequency map. Since objects can hold strings as keys, you could do `var names = {}` and then store each name as the key, like so: `names[People.name]`. Then you could have `names[People.name]` default to zero and increment it by one every time that value pops up in the iteration. Finally, filter that frequency map to get the name that appeared the most. – m-a-r-c-e-l-i-n-o Jun 25 '16 at 04:49
  • @Yamenstein, about this last edit: passing the array as an argument should work. Please, share all your function. – Gerardo Furtado Jun 25 '16 at 06:20
  • @Yamenstein, thanks for sharing the code. It works just fine, I don't understand why it is not working for you. I wrote an answer, check it. – Gerardo Furtado Jun 25 '16 at 06:52

3 Answers3

2

"JavaScript objects can be indexed by strings" means that an object in JavaScript it's like a hash table. The method/field name it's just a String key in that table object.anyName can be written as object['anyName'].

For you exercise you can use that to create a counter of the common used names.

Since it's an exercise I'll not give you the full answer ;) just the idea:

  • For each item in the array, take the person name.
  • Use the person name as key of a "table", if the name is already there sum one to the counter.
  • In the end you'll have an pairs of name/occurrences

If you are very lazy about the exercise... look at the source code of lodash countBy function (https://github.com/lodash/lodash/blob/4.13.1/lodash.js#L8373), it does what you need.

Diego
  • 4,353
  • 1
  • 24
  • 22
  • Hey - just added my comment that I gave before to my original post. But basically I'm just not understanding how to get the array that is created outside of the function into the function so I can sort through it - the coding for the sorting to find the occurences and most common element is done. But I can only do it when I run an array that I have created inside the function through the algorithm. – Yamenstein Jun 25 '16 at 05:58
0

Regarding your edit: passing the array as an argument works fine, you don't need to have the array inside the function:

var fullNames = ['John Smith', 'Jane Smith', 'John Black'];

function commonFirstName(array) {                

            var tempArray = [];
            var fName;
            for (i=0; i < array.length; i++){
                fName = array[i].split(' ').slice(0, -1).join(' ');
                tempArray.push(fName);
            }

            var mostCommon;
            var occurences = 0;
            for (j=0; j < tempArray.length; j++){
                var tempName = tempArray[j];
                var tempCount = 0;
                for (k=0; k < tempArray.length; k++){
                    if (tempArray[k] == tempName){
                        tempCount++;
                    }
                    if (tempCount > occurences){
                        mostCommon = tempName;
                        occurences = tempCount;
                    }
                }
            }
            alert(mostCommon + " : " + occurences);
        }

 commonFirstName(fullNames);

Check the fiddle: https://jsfiddle.net/d2m105pb/

Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
0

All good I have figured out what was wrong. Because of the objects that make up the array People you will need to call the specific variable inside the object - people[i].name for example. Instead of people[i] just by itself.

Thank you for all the input :)

Yamenstein
  • 19
  • 2