Effective Javascript Exercise 5.2. Help organize thoughts

Query question: Using the sample data from this chapter, calculate the average age difference between mothers and children (the age of the mother when the child was born). You can use the middle function defined earlier in this chapter.

Note that not all mothers mentioned in the data are themselves present in the array. The byName object can be useful here, which makes it easy to find people object on their behalf.

JS File: http://eloquentjavascript.net/code/ancestry.js

My approach

  • Create an object with "mothers" as keys, with arrays containing "mother DOB, child name, daughter DOB".

  • Calculate mother's age at birth with daughter DOB - "mother of DOB"

  • Pass the values ​​to the provided mean function written as

    middle function (array) {function plus (a, b) {return a + b; } return array.reduce (plus) /array.length; }


I am stuck at step 1

Step 1 - subdivision

and. remove all data points where mother = null && & where the DOB's mother is unknown (her name is listed as "mother", but there is no separate entry for her)

Filter out all "null" entries:
    var hasMom = ancestry.filter(function(person) {
    return person.mother != null;});

      

Match an array of mothers only names:

  var momSet = hasMom.map(function(person) {return person.mother;});

      

Create a function that will check if a record is contained in a set

function isInSet(set, person) {return set.indexOf(person.name) > -1};

      

Apply function in filter

var hasKnownMother = hasMom.filter(function(person) 
        {return isInSet(momSet, person)});

      

b. create byName object of these mothers with daughter and DOB

 var byName = {};
 hasKnownMother.forEach(function(person) {
       byName[person.name] = [person.born, person.mother];});

      

QUESTION: so far I have filtered 34 records only 10. Cross-validating names and records, I am not getting expected results.

What am I doing wrong? What should I rethink?

from. search .JS file for mother name, add (press?) her DOB to byName object

QUESTION: I have no idea what to do if I want to look up the keys of the byName object (mothers names), map them to the ancestry.JS database keys, and add a .JS DOB entry to my byName object.

I think for a For In loop or binding?

+3


source to share


1 answer


I think the most efficient way would be to create a hash of people using the name as the key so that you don't constantly iterate. After that, you can iterate over the original array again, this time checking that the mother exists in the data and pushing the difference to the output array as you go.

var ancestryJSON = JSON.parse(ANCESTRY_FILE),
byName = {},
ageDifferences = [];

function initNameHash(){
    for(var i = 0, len = ancestryJSON.length; i < len; i++){
        byName[ancestryJSON[i].name] = ancestryJSON[i];
    }
}

function setAgeDifferences(){

    for(var i = 0, len = ancestryJSON.length; i < len; i++){

        var child = ancestryJSON[i];

        if(child.mother !== null &&
           byName[child.mother] !== undefined){

            var mother = byName[child.mother];
            var ageDifference = child.born - mother.born;

            ageDifferences.push(ageDifference);
        }

    }

}

function average(array) { 
    function plus(a, b) { return a + b; } 
    return array.reduce(plus) / array.length; 
}

initNameHash();
setAgeDifferences();

console.log(ageDifferences);
alert(average(ageDifferences));

      



Check out the fiddle: https://jsfiddle.net/oafd8hgL/

+1


source







All Articles