eloquent javascript correlation tableFor explanation

I am taking my first steps in programming and i am stuck with this problem from eloquent, in particular with the weresquirrel problem. Here it goes :

function hasEvent(event, entry) {
 return entry.events.indexOf(event) != -1;
}

function tableFor(event, journal) {
  var table = [0, 0, 0, 0];
   for (var i = 0; i < journal.length; i++) {
     var entry = journal[i], index = 0;
      if (hasEvent(event, entry)) index += 1;
      if (entry.squirrel) index += 2;
      table[index] += 1;
 }
 return table;
}

console.log(tableFor("pizza", JOURNAL));
// ? [76, 9, 4, 1]

I do understand the first function hasevent, it returns true if an entry contains a given event.

what i can't grasp is the tableFor function. I can't get how the function flows and HOW the table gets its values. For example for console.log(tableFor("pizza", JOURNAL)); , we get [76, 9, 4, 1]. But How for god's sake ?

The journal is supplied by the book and looks like this :

var JOURNAL = [
  {"events":["pizza","exercise","weekend"],"squirrel":false},
  {"events":["bread","pudding","brushed teeth","weekend","touched 
  tree"],"squirrel":false},
  {"events":["carrot","nachos","brushed 
  teeth","cycling","weekend"],"squirrel":false},
  {"events":["brussel sprouts","ice cream","brushed 
  teeth","computer","weekend"],"squirrel":false},
  {"events":["potatoes","candy","brushed 
  teeth","exercise","weekend","dentist"],"squirrel":false},
  {"events":["brussel sprouts","pudding","brushed 
  teeth","running","weekend"],"squirrel":false},
  {"events":["pizza","brushed teeth","computer","work","touched 
  tree"],"squirrel":false},
  {"events":["bread","beer","brushed 
  teeth","cycling","work"],"squirrel":false},
  {"events":["cauliflower","brushed teeth","work"],"squirrel":false},
  {"events":["pizza","brushed teeth","cycling","work"],"squirrel":false},
  {"events":["lasagna","nachos","brushed teeth","work"],"squirrel":false},
  {"events":["brushed teeth","weekend","touched tree"],"squirrel":false},
  {"events":["lettuce","brushed 
   teeth","television","weekend"],"squirrel":false},
  {"events":["spaghetti","brushed teeth","work"],"squirrel":false},
  {"events":["brushed teeth","computer","work"],"squirrel":false},
  {"events":["lettuce","nachos","brushed teeth","work"],"squirrel":false},
  {"events":["carrot","brushed teeth","running","work"],"squirrel":false} ...etc

What i understand is that an event is passed as a parameter and it looks through the array of objects in Jounral to see if it's present. But how does the counting take place ?

if (entry.squirrel) index += 2;

Why is this +2 ? why not index += 3; or index += 4; ???

and finally why table[index] += 1; ???

For example the first loop goes like this, for : console.log(tableFor("pizza", JOURNAL));

//FLOW
i=0;

from the first line above in journal, pizza is present.

     if (hasEvent(event, entry)) index += 1;

so index is incremented and becomes 1.it continues to :

     if (entry.squirrel) index += 2; 

squirel is false, so nothing happens to index.If squirel were to be found, why is it +2 ???

then table[index] += 1 i can't understand from this point.

Can someone please break it down for me ? It would be very helpful for my training.

Thank you in advance.

Answers:

Answer

The table array is a count of entries that meet different criteria. table[3] is the count of entries where both entry.squirrel are hasEvent(event, entry) are true. table[2] is the count where just entry.squirrel is true, table[1] is the count where just hasEvent(event, entry) is true, and table[0] is the count where neither is true.

So the logic is that index starts at 0. If hasEvent(event, entry) is true, we add 1 to it. If entry.squirrel is true we add 2 to it. The result is that if both are true, we end up adding 3. And if neither is true we don't add anything, so it's still 0.

Then we add 1 to table[index] to increment that counter.

Answer
  1. About JOURNAL :: Each entry has list of events and become squirrel? bool value.
  2. About CODE ::

input --> event ( one of [beer, bread, brushed teeth, brussel sprouts, candy, carrot, cauliflower, computer, cycling, dentist, exercise, ice cream, lasagna, lettuce, nachos, peanuts, pizza, potatoes, pudding, reading, running, spaghetti, television, touched tree, weekend, work]).

output --> table(1 X 4)

table[0] -- Number of entries in JOURNAL which does not has given event and  squirrel is False.
table[1] -- Number of entries in JOURNAL which has given event and  squirrel is False.
table[2] -- Number of entries in JOURNAL which does not has given event and  squirrel is True.
table[3] -- Number of entries in JOURNAL which has given event and  squirrel is True.
**hasEvent(event, entry)  entry.squirrel  table[index]** 
False                   False           table[0] += 1
True                    False           table[1] += 1
False                   True            table[2] += 1
True                    True            table[3] += 1
Answer

I'm going through this same book and I came across this discussion and thought I could contribute as well. I'm a beginner as well so please correct me if I'm wrong. Anyway, this is how I understand it:

First, we call the function tableForwith two parameters "pizza" (a string; one of the possible causes for Jacques to turn into a squirrel we have to check) and JOURNAL(an object; it consists of the following properties: "events" - possible causes - and "squirrel" - whether Jacques turned into a squirrel that day or not). The JOURNAL itself is an array consisting of multiple objects. Also, the "events"property is an array as well.

The two parameters "pizza" and JOURNAL are then passed to the tableFor parameters event and journal, so now "pizza" is event and JOURNAL is journal.

Since the end result has to be an array consisting of 4 elements so we could calculate the correlation later, we declare a variable to store this array: var table = [0, 0, 0, 0];Then we have to figure a way to make the values of the array to increment themselves when needed: for (var i = 0; i < journal.length; i++) which means we are making a loop to go through every element of the journal. i = 0 means we're currently looking for "pizza" in the 1st element of the journal array and then move on the the 2nd one. 3rd one etc. until the last element of the array, hence i < journal.length.

var entry = journal[i], index = 0; means that we take the n-th element of the array and assign it to the entry variable, and define index (the current index in the table array) as 0.

Here we call another function hasEvent:

<pre>if (hasEvent(event, entry)) index += 1;
if (entry.squirrel) index += 2;</pre>

<pre>function hasEvent(event, entry) {
return entry.events.indexOf(event) != -1;
}</pre>

which means we take the event ("pizza") and the entry the 0th element of journal array and check whether it contains the key word "pizza". If it doesn't contain it indexOf willll return -1, if it does it'll return the first index at which the given element is present. In our 1st case, {"events":["carrot","exercise","weekend"],"squirrel":false}, there's no "pizza", so indexOf will return -1. This line if (hasEvent(event, entry)) index += 1; asks whether hasEvent is true (whether indexOf is not equal -1). In our case it is equal -1, so we don't add 1 to index. And this line if (entry.squirrel) index += 2; asks whether it's true that Jacques has turned into a squirrel (we can see that it's false), so we don't add 2 to index. So our current index we're working with remains at 0. And now we increase it by 1 (table[index] += 1;), so in the very first scenario we have the following result [1, 0, 0, 0].

It's also worth mentioning that in our table array:

`index 0 = 00 (no pizza, no squirrel)
index 1 = 10 (pizza, no squirrel)
index 2 = 01 (no pizza, squirrel)
index 3 = 11 (pizza, squirrel)`

So depending on each case, we'll move from index 0 to index 1,2,3 or stay at index 0 and increase it by one depending on which conditions are met. I hope someone finds my explanation/understanding useful.

Answer

I was also confused with the following:

if (entry.events.includes(event)) index += 1;
if (entry.squirrel) index += 2;
table[index] += 1;

This actually means: if (entry.events.includes(event)) index += 1; === true, add 1 to index. In that case, we can translate it as table[1] += 1

And if below is true as well,

if (entry.squirrel) index += 2;

then: table[3] += 1

table[3]is populated only if squirrel and entry=== true

if (entry.squirrel) index += 2is increased by 2 because squirrelis true in table[2].

table[index] is actually just an index we want to use as a target.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.