Reduce Method and From method - confusion

Hi there,

I am following a react course (CS50M) https://github.com/SilvercutYaz/cs50M

I am having problem understanding some JS code:

  1. What is the addkeys doing? it takes in a val and key and then returns the key? and a spread operator? im not entirely sure what’s happening here. (Contacts.js)

// add keys to based on index
const addKeys = (val, key) => ({key, ...val})

// create an array of length NUM_CONTACTS and add keys
export default Array.from({length: NUM_CONTACTS}, createContact).map(addKeys)
  1. there is an reduce and from method below that i dont really understand ( SectionListContacts.js
const SectionListContacts = props => {
  const contactsByLetter = props.contacts.reduce((obj, contact) => {
    const firstLetter = contact.name[0].toUpperCase()
    return {
      ...obj,
      [firstLetter]: [...(obj[firstLetter] || []), contact],
    }
  }, {})

  const sections = Object.keys(contactsByLetter).sort().map(letter => ({
    data: contactsByLetter[letter],
    title: letter,
  }))

i would appreciate your help if i could understand this. thanks

fantastic explanation for addkeys thanks. why must val be the first argument that is passed in? 3) i changed the arguments around and it produces a different result. So i am not 100% sure why that is.

// add keys to based on index
const addKeys = (val, key) => ({key:key, ...val})

// create an array of length NUM_CONTACTS and add keys
const generate = () => Array.from({length: NUM_CONTACTS}, createContact)

0: {name: "Lincoln Davies", phone: "825-442-5845"}
1: {name: "Andrew Mitchell", phone: "881-424-6703"}
// add keys to based on index
const addKeys = (val, key) => ({key:key, ...val})

// create an array of length NUM_CONTACTS and add keys
const generate = () => Array.from({length: NUM_CONTACTS}, createContact).map(addKeys)

0: {key: 0, name: "Scarlett King", phone: "309-869-1290"}
1: {key: 1, name: "Scarlett Scott", phone: "843-747-7404"}
// add keys to based on index
const addKeys = (key, val) => ({key:key, ...val})

// create an array of length NUM_CONTACTS and add keys
const generate = () => Array.from({length: NUM_CONTACTS}, createContact).map(addKeys)

0:
key: {name: "Stella Murphy", phone: "603-639-3162"}
__proto__: Object
1:
key: {name: "Alexander Young", phone: "818-135-7262"}
__proto__: Object

Also just confirming the spread operator below for future reference. Indeed the same:

May i explain what i think is happening and see if i’m wrong?

  1. obj is a list/section that displays on the screen (not the full contacts array; technically obj will display the section of arrays only) with key value pairs

  2. contact is one contact with key value pairs

  3. the reduce function firstly:
    a) sets a function that capitalises the first letter of the string of “name”
    b) returns a new object with i) the old object key value pairs and ii) appends a new key value pair such that name: Amanda should return key A: value [all objects cloned but with contact.name uppercased]

iii) i think the “contact” refers to the object that is being mutated? i.e., […obj[firstletter]] is applied to contact. yes?

Your response is hugely appreciated.

const SectionListContacts = props => {
  const contactsByLetter = props.contacts.reduce((obj, contact) => {
    const firstLetter = contact.name[0].toUpperCase()
    return {
      ...obj,
      [firstLetter]: [...(obj[firstLetter] || []), contact],
    }
  }, {})

I will look at the challenge. thanks :slight_smile:

array .map( function(currentValue, index, arr), thisValue )

currentValue Required. The value of the current element
index Optional. The array index of the current element