My Raw Notes for the Week of 11-15-2021
Tags: javascript, arrays, objects, funcprogramming
Published: 2021-11-22 22:59:20

```
ENGLISH:

Paraphrase: As a general rule,
a 'for' loop works better for iterating through arrays,
and a 'for...in' loop works better for iterating through objects.

forEach() returns 'undefined'.
map() returns a new array.
```
```javascript
CODE:

// JS
function createSuspectObjects(name) {
  return { // returning an object
    name: name,
    color: name.split(' ')[1],
    speak() {
      console.log(`my name is ${this.name}`)
    }
  }
}

const suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White']

let suspectsList = []

suspects.forEach(suspect => {
  suspectsList.push(createSuspectObjects(suspect))
})

console.log(suspectsList)

//-------------------------------------------------------------------

// JS
const rooms = ['observatory', 'ballroom', 'library']

let logger = function(val) {
  console.log(val)
}

rooms.forEach(room => {
  logger(room)
})

//-------------------------------------------------------------------

// JS
// CREATING the '_.each' function
const _ = {}

_.each = function(list, callback) {
  if (Array.isArray(list)) {
    // loop through array
    for (let i = 0; i < list.length; i++) {
      // call the callback with a list item
      callback(list[i], i, list) // (value, index, list)
    }
  } else {
    // loop through object
    for (let key in list) {
      // call the callback with a list item
      callback(list[key], key, list) // (value, index, list)
    }
  }
}

// USING the '_.each' function created above (note only doing with array here...she didn't get around to example with object)
_.each(['sally', 'georgie', 'porgie'], function(name, i, list) { // for sake of this example, assume that 'list' people get older left to right
  if (list[i + 1]) { // evaluates to 'true' when 'list[i + 1]' exists
    console.log(name, 'is younger than', list[i + 1])
  } else {
    console.log(name, 'is the oldest')
  }
})

//-------------------------------------------------------------------

// JS
arr = [2, 4, 6, 8, 10]

// note that when using the 'map' method, you can use curly braces or not, but remember that using curly braces necessitates using the 'return' keyword
// each of the below two examples returns the same thing

let withoutThem = arr.map(num => num * 2)
console.log(withoutThem) // [4, 8, 12, 16, 20]

let withThem = arr.map(num => {return num * 2})
console.log(withThem) // [4, 8, 12, 16, 20]

//-------------------------------------------------------------------

// JS
// to better see how the 'map' method works with not just its 'element' parameter but also its 'index' and 'array' parameters
const arr = [1, 4, 9, 16]
const mapIt = arr.map((element, index, array) => {
  return `element is ${element}, index is ${index}, array is ${array}`
})
console.log(mapIt)

//-------------------------------------------------------------------

// JS
function makeObj(name) {
  return {
    name: name,
    color: name.split(' ')[1],
    speak() {
      console.log(`my name is ${this.name}`)
    }
  }
}

console.log(makeObj('John Blue')) // {name: 'John Blue', color: 'Blue', speak: ƒ} (remember that the 'speak' method isn't called here, so 'my name is John Blue' can't be seen/accessed in the console)
console.log(makeObj('John Blue').speak()) // my name is John Blue (technically this is logged at the 'console.log' in the 'speak' method)

/* Robert:
When you run 'console.log(makeObj('John Blue'))'... 

...makeObj is called
...an object is returned,
which contains a method ('speak'),
but 'speak' isn't called,
so 'my name is John Blue' isn't logged.

When you run 'console.log(makeObj('John Blue').speak())'...

...makeObj is called
...an object is returned,
which contains a method ('speak'),
which you call immediately (thanks to 'chaining', e.g., thing.method.method),
and 'speak' logs 'my name is John Blue'.

Returning the object doesn't also call the function.
It just returns the object (containing all the properties and functions).
*/

//-------------------------------------------------------------------

// JS
function createSuspectObjects(name) {
  return { // returning an object
    name: name,
    color: name.split(' ')[1],
    speak() {
      console.log(`my name is ${this.name}`)
    }
  }
}

const suspects = ['Miss Scarlet', 'Colonel Mustard', 'Mr. White']

let suspectsList = suspects.map(suspect => createSuspectObjects(suspect))

console.log(suspectsList)

//-------------------------------------------------------------------

// JS
// CREATING the '_.map' function (must be put in console to log result)
const _ = {}

_.map = function(list, callback) {
  // create empty array to store
  const newArr = []
  // loop through list
  for (let i = 0; i < list.length; i++) {
    // push to the new array what 'callback' returns
    newArr.push(callback(list[i], i, list))
  }
  // return new array
  return newArr
}

/* Note that instead of using the 'for' loop above, you could just use forEach() like this:
list.forEach((el, i, list) => {
  newArr.push(callback(el, i, list));
})
*/

// USING the '_.map' function created above
_.map([1, 2, 3], function(num) {return num + 1})

//-------------------------------------------------------------------

// JS
// from http://csbin.io/functional but included because it ties in:
// Challenge 4
let alphabet = ''
const letters = ['a', 'b', 'c', 'd']
const forEach = (array, callback) => {
  for (let i = 0; i < array.length; i++) {
    callback(array[i])
  }
}
forEach(letters, char => alphabet += char) // i.e.: 'forEach(letters, function(char) {return alphabet += char})'
console.log(alphabet) // abcd

//-------------------------------------------------------------------

// JS
// from fCC's "Implement the filter Method on a Prototype" but included because it ties in:
const s = [23, 65, 98, 5]

Array.prototype.myFilter = function(callback) {
  const newArray = []
  s.forEach(item => {
    if (callback(item)) {  // i.e.: 'callback(item) === true'
      newArray.push(item)
    }
  })
  return newArray;
}

const new_s = s.myFilter(function(item) {
  return item % 2 === 1
})

console.log(new_s) // [23, 65, 5]

//-------------------------------------------------------------------

// JS
// CREATING the '_.filter' function
const _ = {}

_.filter = function(arr, callback) {
  const newArr = []
  for (let i = 0; i < arr.length; i++) {
    if (callback(arr[i], i, arr)) { // i.e.: 'callback(arr[i], i, arr) === true'
      newArr.push(arr[i])
    }
  }
  return newArr
}

/* Note that instead of using the 'for' loop above, you could use '_.each':
_.each(arr, function(item, i, list) {
  if (callback(item, i, list)) {
    newArr.push(item)
  }
})
*/

/* And note that instead of using the 'for' loop or '_.each', you could use 'forEach()':
arr.forEach((item, i, list) => {
  if (callback(item, i, list)) {
    newArr.push(item)
  }
})
*/

// USING the '_.filter' function created above
const videoData = [
  {
    name: 'Miss Scarlet',
    present: true,
    rooms: [
      {kitchen: false},
      {ballroom: false},
      {conservatory: false},
      {'dining room': false},
      {'billiard room': false},
      {library: false}
    ]
  },
  {
    name: 'Mrs. White',
    present: false,
    rooms: [
      {kitchen: false},
      {ballroom: false},
      {conservatory: false},
      {'dining room': false},
      {'billiard room': false},
      {library: false}
    ]
  },
  {
    name: 'Reverend Green',
    present: true,
    rooms: [
      {kitchen: false},
      {ballroom: false},
      {conservatory: false},
      {'dining room': false},
      {'billiard room': false},
      {library: false}
    ]
  },
  {
    name: 'Rusty',
    present: false,
    rooms: [
      {kitchen: false},
      {ballroom: false},
      {conservatory: false},
      {'dining room': false},
      {'billiard room': false},
      {library: false}
    ]
  },
  {
    name: 'Colonel Mustard',
    present: true,
    rooms: [
      {kitchen: false},
      {ballroom: false},
      {conservatory: false},
      {'dining room': false},
      {'billiard room': false},
      {library: false}
    ]
  },
  {
    name: 'Professor Plum',
    present: true,
    rooms: [
      {kitchen: false},
      {ballroom: false},
      {conservatory: false},
      {'dining room': false},
      {'billiard room': false},
      {library: false}
    ]
  }
]

console.log(
  _.filter(videoData, function(suspectObj) {
    return suspectObj.present
  })
)
```