4,461
edits
Line 796: | Line 796: | ||
// {name: "Frederick Douglass", canRead: false, canWrite: false} | // {name: "Frederick Douglass", canRead: false, canWrite: false} | ||
</source> | </source> | ||
an impure function --it changes DOM | |||
<source lang="js"> | |||
function Header(text) { | |||
let h1 = document.createElement("h1"); | |||
h1.innerText = text; | |||
document.body.appendChild(h1); | |||
} | |||
Header("Header() caused side effects"); | |||
</source> | |||
In React, UI is expressed with pure functions. e.g. | |||
<source lang="js"> | |||
const Header = props => <h1>{props.title}</h1>; | |||
</source> | |||
==== Guideline for writing pure functions ==== | |||
# at least one argument | |||
# return a value or another function | |||
# should not change or mutate any of its arguments | |||
=== Data Transformations === | |||
via Array.map and Array.reduce | |||
using Array.join | |||
<source lang="js"> | |||
const schools = ["Yorktown", "Washington & Lee", "Wakefield"]; | |||
console.log(schools.join(", ")); | |||
// "Yorktown, Washington & Lee, Wakefield" | |||
</source> | |||
create a new array of the schools that begin with the letter "W" | |||
<source lang="js"> | |||
const wSchools = schools.filter(school => school[0] === "W"); | |||
console.log(wSchools); | |||
// ["Washington & Lee", "Wakefield"] | |||
</source> | |||
when removing an item from an array, use Array.filter over .pop() or .splice() because .filter() is immutable | |||
<source lang="js"> | |||
const cutSchool = (cut, list) => list.filter(school => school !== cut); | |||
console.log(cutSchool("Washington & Lee", schools).join(", ")); | |||
// "Yorktown, Wakefield" | |||
console.log(schools.join("\n")); | |||
// Yorktown | |||
// Washington & Lee | |||
// Wakefield | |||
</source> | |||
Array.map takes a function as its argument which will be invoked once for every item in the array, and whatever it returns will be added to the new array | |||
<source lang="js"> | |||
const highSchools = schools.map(school => `${school} High School`); | |||
console.log(highSchools.join("\n")); | |||
// Yorktown High School | |||
// Washington & Lee High School | |||
// Wakefield High School | |||
console.log(schools.join("\n")); | |||
// Yorktown | |||
// Washington & Lee | |||
// Wakefield | |||
</source> | |||
e.g. return an object for every school | |||
<source lang="js"> | |||
const highSchools = schools.map(school => ({ name: school })); | |||
console.log(highSchools); | |||
// [ | |||
// { name: "Yorktown" }, | |||
// { name: "Washington & Lee" }, | |||
// { name: "Wakefield" } | |||
// ] | |||
</source> | |||
pure f(x) that changes one object in an array of objects | |||
<source lang="js"> | |||
let schools = [ | |||
{ name: "Yorktown" }, | |||
{ name: "Stratford" }, | |||
{ name: "Washington & Lee" }, | |||
{ name: "Wakefield" } | |||
]; | |||
const editName = (oldName, name, arr) => | |||
arr.map(item => { | |||
if (item.name === oldName) { | |||
return { | |||
...item, | |||
name | |||
}; | |||
} else { | |||
return item; | |||
} | |||
}); | |||
let updatedSchools = editName("Stratford", "HB Woodlawn", schools); | |||
console.log(updatedSchools[1]); // { name: "HB Woodlawn" } | |||
console.log(schools[1]); // { name: "Stratford" } | |||
// equivalent to | |||
const editName = (oldName, name, arr) => | |||
arr.map(item => (item.name === oldName ? { ...item, name } : item)); | |||
</source> | |||
transform schools object into an array of schools: | |||
<source lang="js"> | |||
const schools = { | |||
Yorktown: 10, | |||
"Washington & Lee": 2, | |||
Wakefield: 5 | |||
}; | |||
const schoolArray = Object.keys(schools).map(key => ({ | |||
name: key, | |||
wins: schools[key] | |||
})); | |||
console.log(schoolArray); | |||
// [ | |||
// { | |||
// name: "Yorktown", | |||
// wins: 10 | |||
// }, | |||
// { | |||
// name: "Washington & Lee", | |||
// wins: 2 | |||
// }, | |||
// { | |||
// name: "Wakefield", | |||
// wins: 5 | |||
// } | |||
// ] | |||
</source> | |||
<code>reduce</code> and <code>reduceRight</code> are used to trasnform an array into any value, including a number, string, boolean, object, or even a function | |||
maximum number in an array of numbers | |||
<source lang="js"> | |||
const ages = [21, 18, 42, 40, 64, 63, 34]; | |||
const maxAge = ages.reduce((max, age) => { | |||
console.log(`${age} > ${max} = ${age > max}`); | |||
if (age > max) { | |||
return age; | |||
} else { | |||
return max; | |||
} | |||
}, 0); | |||
console.log("maxAge", maxAge); | |||
// 21 > 0 = true | |||
// 18 > 21 = false | |||
// 42 > 21 = true | |||
// 40 > 42 = false | |||
// 64 > 42 = true | |||
// 63 > 64 = false | |||
// 34 > 64 = false | |||
// maxAge 64 | |||
// equivalent to | |||
const max = ages.reduce((max, value) => (value > max ? value : max), 0); | |||
</source> | |||
reduce takes two arguments: a callback function & an original value | |||
reduceRight simply starts reducing from the end of the array rather than the beginning |