mirror of
https://github.com/Stone-Red-Code/website.git
synced 2026-09-09 16:06:14 +02:00
Merge pull request #91 from supergrecko/resource-arrays-js
resources: iterate over javascript arrays resource
This commit is contained in:
@@ -1,129 +1,174 @@
|
|||||||
---
|
---
|
||||||
authors:
|
authors:
|
||||||
- "veksen#1060"
|
- "veksen#1060"
|
||||||
|
- "supergrecko#3434"
|
||||||
created_at: "2019/07/27"
|
created_at: "2019/07/27"
|
||||||
title: Iterative vs Functional array helpers
|
title: Iterative vs Functional array helpers
|
||||||
---
|
---
|
||||||
|
|
||||||
-- placeholder --
|
This article assumes that you are comfortable with the very basics of JavaScript arrays, and how they differ to objects. This article teaches you how to use the built-in functions for arrays.
|
||||||
|
|
||||||
## find
|
Each of the functions described in this article use a callback function. If you are not familiar with callback functions I would advise you to read [this article by Mozilla](https://developer.mozilla.org/en-US/docs/Glossary/Callback_function) before continuing.
|
||||||
|
|
||||||
|
## Getting a specific element using `find()`
|
||||||
|
|
||||||
|
It's not rare to need to look for some specific element based on a criteria. `find()` makes this particularly easy. It takes a function, taking a few arguments:
|
||||||
|
|
||||||
|
- current item
|
||||||
|
- index of current item (optional)
|
||||||
|
- original array reference (optional)
|
||||||
|
|
||||||
|
The `.find()` function loops over the items, if the callback function evaluates to truthy the item is returned, and the loop ends.
|
||||||
|
|
||||||
|
If no items evaluated to truthy `undefined` will be returned.
|
||||||
|
|
||||||
|
If you're only interested in the presence of an element, consider using `some()`, which instead returns a boolean.
|
||||||
|
|
||||||
|
Conventionally, in an iterative approach, this would be done using a preset variable, and looping through our array.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// given our data
|
||||||
const users = [
|
const users = [
|
||||||
{ name: "Joe", age: 25 },
|
{ name: "Joe", age: 25 },
|
||||||
{ name: "John", age: 17 },
|
{ name: "John", age: 17 },
|
||||||
{ name: "Jane", age: 16 },
|
{ name: "Jane", age: 16 },
|
||||||
]
|
]
|
||||||
```
|
|
||||||
|
|
||||||
Iterative way:
|
// functional way
|
||||||
|
const foundUser = users.find(user => user.name === "John")
|
||||||
|
|
||||||
```js
|
// iterative way
|
||||||
let foundUser = null
|
let foundUser = null
|
||||||
users.forEach(user => {
|
users.forEach(user => {
|
||||||
if (user.name === "John") {
|
if (user.name === "John") {
|
||||||
foundUser = user
|
foundUser = user
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
console.log(foundUser) // outputs { name: "John", age: 17 }
|
||||||
```
|
```
|
||||||
|
|
||||||
Functional way:
|
## Keep specific items using `filter()`
|
||||||
|
|
||||||
```js
|
`filter()` makes it easy to keep specific items based on a criteria.
|
||||||
const foundUser = users.find(user => user.name === "John")
|
|
||||||
```
|
|
||||||
|
|
||||||
## filter
|
It takes a function, taking a few arguments:
|
||||||
|
|
||||||
|
- current item
|
||||||
|
- index of current item (optional)
|
||||||
|
- original array reference (optional)
|
||||||
|
|
||||||
|
`filter()` does not modify (mutate) the original array, instead, it returns a new one.
|
||||||
|
|
||||||
|
If the callback function evaluates to truthy, this specific item is pushed to the final array, otherwise it is ignored.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// given our data
|
||||||
const users = [
|
const users = [
|
||||||
{ name: "Joe", age: 25 },
|
{ name: "Joe", age: 25 },
|
||||||
{ name: "John", age: 17 },
|
{ name: "John", age: 17 },
|
||||||
{ name: "Jane", age: 16 },
|
{ name: "Jane", age: 16 },
|
||||||
]
|
]
|
||||||
```
|
|
||||||
|
|
||||||
Iterative way:
|
// functional way
|
||||||
|
const youngerUsers = users.filter(user => user.age < 18)
|
||||||
|
|
||||||
```js
|
// iterative way
|
||||||
const youngerUsers = []
|
const youngerUsers = []
|
||||||
users.forEach(user => {
|
users.forEach(user => {
|
||||||
if (user.age < 18) {
|
if (user.age < 18) {
|
||||||
youngerUsers.push(user)
|
youngerUsers.push(user)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
console.log(youngerUsers) // outputs [ { name: "John", age: 17 }, { name: "Jane", age: 16 } ]
|
||||||
```
|
```
|
||||||
|
|
||||||
Functional way:
|
## Modifying all elements of an array using `.map()`
|
||||||
|
|
||||||
```js
|
It's common to want to modify every element of an array with some logic, and `map()` makes this easy.
|
||||||
const youngerUsers = users.filter(user => user.age < 18)
|
|
||||||
```
|
|
||||||
|
|
||||||
## map
|
It takes a function, taking a few arguments:
|
||||||
|
|
||||||
|
- current item
|
||||||
|
- index of current item (optional)
|
||||||
|
- original array reference (optional)
|
||||||
|
|
||||||
|
The function loops through the array and runs the callback function on each element. Just like the `filter()` function, `map()` does not mutate the original array.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// given our data
|
||||||
const users = [
|
const users = [
|
||||||
{ name: "Joe", age: 25 },
|
{ name: "Joe", age: 25 },
|
||||||
{ name: "John", age: 17 },
|
{ name: "John", age: 17 },
|
||||||
{ name: "Jane", age: 16 },
|
{ name: "Jane", age: 16 },
|
||||||
]
|
]
|
||||||
```
|
|
||||||
|
|
||||||
Iterative way:
|
// functional way
|
||||||
|
const userNames = users.map(user => user.name)
|
||||||
|
|
||||||
```js
|
// iterative way
|
||||||
const userNames = []
|
const userNames = []
|
||||||
users.forEach(user => {
|
users.forEach(user => {
|
||||||
userNames.push(user.name)
|
userNames.push(user.name)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
console.log(userNames) // outputs [ "Joe", "John", "Jane" ]
|
||||||
```
|
```
|
||||||
|
|
||||||
Functional way:
|
## Running custom logic using an array using `.reduce()`
|
||||||
|
|
||||||
```js
|
`reduce()` is often less understood, but it's not that complicated once you get the basics. Itself, it takes 2 arguments, a function, and an initial value. The function takes a few arguments:
|
||||||
const userNames = users.map(user => user.name)
|
|
||||||
```
|
|
||||||
|
|
||||||
## reduce
|
- accumulator, that is a reference to the current value that was last returned, or the initial value
|
||||||
|
- current value, the currently looped element
|
||||||
|
- current index (optional)
|
||||||
|
- original array (optional)
|
||||||
|
|
||||||
|
The `reduce()` function returns the accumulative result after the callback has been ran on each element.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// given our data
|
||||||
const users = [
|
const users = [
|
||||||
{ name: "Joe", age: 25 },
|
{ name: "Joe", age: 25 },
|
||||||
{ name: "John", age: 17 },
|
{ name: "John", age: 17 },
|
||||||
{ name: "Jane", age: 16 },
|
{ name: "Jane", age: 16 },
|
||||||
]
|
]
|
||||||
```
|
|
||||||
|
|
||||||
Iterative way:
|
// functional way
|
||||||
|
const totalAge = users.reduce((acc, user) => acc + user.age, 0)
|
||||||
|
|
||||||
```js
|
// iterative way
|
||||||
let totalAge = 0
|
let totalAge = 0
|
||||||
users.forEach(user => {
|
users.forEach(user => {
|
||||||
totalAge += user.age
|
totalAge += user.age
|
||||||
})
|
})
|
||||||
|
|
||||||
|
console.log(totalAge) // outputs 58
|
||||||
```
|
```
|
||||||
|
|
||||||
Functional way:
|
## Checking if any element matches a condition with `some()`
|
||||||
|
|
||||||
```js
|
`some()` is very similar to `find()`, except it returns a boolean on a match.
|
||||||
const totalAge = users.reduce((acc, user) => acc + user.age, 0)
|
|
||||||
```
|
|
||||||
|
|
||||||
## some
|
Conventionally, we would prepare some variable with a value of false, loop over all of the elements, and exit the loop once we find a match. The function takes a callback function which accepts some parameters.
|
||||||
|
|
||||||
|
- the current element
|
||||||
|
- the array index of the current element (optional)
|
||||||
|
- a reference to the array (optional)
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// given our data
|
||||||
const users = [
|
const users = [
|
||||||
{ name: "Joe", age: 25 },
|
{ name: "Joe", age: 25 },
|
||||||
{ name: "John", age: 17 },
|
{ name: "John", age: 17 },
|
||||||
{ name: "Jane", age: 16 },
|
{ name: "Jane", age: 16 },
|
||||||
]
|
]
|
||||||
```
|
|
||||||
|
|
||||||
Iterative way:
|
// functional way
|
||||||
|
const hasYoungUsers = users.some(user => user.age < 18)
|
||||||
|
|
||||||
```js
|
// iterative way
|
||||||
let hasYoungUsers = false
|
let hasYoungUsers = false
|
||||||
for (let i = 0; users.length > i; i++) {
|
for (let i = 0; users.length > i; i++) {
|
||||||
if (user > 18) {
|
if (user > 18) {
|
||||||
@@ -131,27 +176,26 @@ for (let i = 0; users.length > i; i++) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
|
||||||
|
|
||||||
Functional way:
|
console.log(hasYoungUsers) // outputs true
|
||||||
|
|
||||||
```js
|
|
||||||
const hasYoungUsers = users.some(user => user.age < 18)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## every
|
## every
|
||||||
|
|
||||||
|
`every()` is similar to `some()`. The difference is that `some()` test if one or more of the items match. `every()` tests if every item in the array matches.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// given our data
|
||||||
const users = [
|
const users = [
|
||||||
{ name: "Joe", age: 25 },
|
{ name: "Joe", age: 25 },
|
||||||
{ name: "John", age: 17 },
|
{ name: "John", age: 17 },
|
||||||
{ name: "Jane", age: 16 },
|
{ name: "Jane", age: 16 },
|
||||||
]
|
]
|
||||||
```
|
|
||||||
|
|
||||||
Iterative way:
|
// functional way
|
||||||
|
const allUsersAreOldEnough = users.every(user => user.age < 18)
|
||||||
|
|
||||||
```js
|
// iterative way
|
||||||
let allUsersAreOldEnough = true
|
let allUsersAreOldEnough = true
|
||||||
for (let i = 0; users.length > i; i++) {
|
for (let i = 0; users.length > i; i++) {
|
||||||
if (user.age > 18) {
|
if (user.age > 18) {
|
||||||
@@ -159,23 +203,21 @@ for (let i = 0; users.length > i; i++) {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
console.log(allUsersAreOldEnough) // outputs false
|
||||||
|
|
||||||
Functional way:
|
|
||||||
|
|
||||||
```js
|
|
||||||
const hasYoungUsers = users.every(user => user.age < 18)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## includes
|
## includes
|
||||||
|
|
||||||
|
The `includes()` function tests if the passed item exists inside the array. It returns a boolean value.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
// given our data
|
||||||
const pets = ["cat", "dog", "bat"]
|
const pets = ["cat", "dog", "bat"]
|
||||||
```
|
|
||||||
|
|
||||||
Iterative way:
|
// functional way
|
||||||
|
const found = pets.includes("dog")
|
||||||
|
|
||||||
```js
|
// iterative way
|
||||||
let found = false
|
let found = false
|
||||||
pets.forEach(pet => {
|
pets.forEach(pet => {
|
||||||
if (pet === "dog") {
|
if (pet === "dog") {
|
||||||
@@ -184,11 +226,7 @@ pets.forEach(pet => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// or most of the time done with indexOf
|
// or most of the time done with indexOf
|
||||||
pets.indexOf("dogs") > 0
|
const found = pets.indexOf("dog") > 0
|
||||||
```
|
|
||||||
|
|
||||||
Functional way:
|
console.log(found) // outputs true
|
||||||
|
|
||||||
```js
|
|
||||||
pets.includes("dogs")
|
|
||||||
```
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user