SoFunction
Updated on 2025-03-06

Things you should know about JavaScript arrays (recommended)

First make a bold statement: loops are often useless and make the code difficult to read.
When it comes to iterating an array, no matter you want to find elements, sort or anything else, there is an array method for you to use.

However, despite their usefulness, some of them are still unknown. I will try to show you some useful methods. Take this article as a guide to JavaScript array methods.

Note: Before you start, you have to understand one thing: I prefer functional programming. So the method I tend to use doesn't directly change the original array. I avoided side effects in this way. I'm not saying that the array should not be changed, but at least understand which methods will change, and which will have side effects. Side effects lead to unwanted changes, and unwanted changes bring bugs!

After understanding this, we can start the main text.

Essential
When dealing with arrays, there are four things you should be clear about: map, filter, reduce and expand operators. They are powerful.

map

You can use it in many cases. Basically, consider using map every time you need to modify elements of an array.
It accepts a parameter: a method, called on each array element. Then return a new array, so there are no side effects.

const numbers = [1, 2, 3, 4]

const numbersPlusOne = (n => n + 1) // +1 per element(numbersPlusOne) // [2, 3, 4, 5]

You can also create a new array that preserves a special property of the object:

const allActivities = [
 { title: 'My activity', coordinates: [50.123, 3.291] },
 { title: 'Another activity', coordinates: [1.238, 4.292] },
 // etc.
]

const allCoordinates = (activity => )
(allCoordinates) // [[50.123, 3.291], [1.238, 4.292]]

So, remember, consider using map when you need to convert arrays.

filter

The name of this method is very accurate here: use it when you want to filter arrays.
As map does, it accepts a function as its only parameter, called on each element of the array. This method returns a boolean value:

  1. true if you need to preserve elements in an array
  2. false if you don't want to keep it

Then you get a new array with the elements you want to keep.
For example, you can keep only odd numbers in an array:

const numbers = [1, 2, 3, 4, 5, 6]
const oddNumbers = (n => n % 2 !== 0)
(oddNumbers) // [1, 3, 5]

Or you can remove special items in the array:

const participants = [
 { id: 'a3f47', username: 'john' },
 { id: 'fek28', username: 'mary' },
 { id: 'n3j44', username: 'sam' },
]

function removeParticipant(participants, id) {
 return (participant =>  !== id)
}

(removeParticipant(participants, 'a3f47')) // [{ id: 'fek28', username: 'mary' }, { id: 'n3j44', username: 'sam' }];

reduce

I personally think it is the most difficult method to understand. But if you get to know it, there are a lot of crazy things you can do with it.
Basically, reduce uses an array with values ​​and then combines it into a new value. It accepts two parameters, a callback method is our reducer and an optional initialized value (default is the first item in the array). This reducer uses four parameters:

  1. Accumulated: The return value accumulated in your reducer
  2. The value of the current array
  3. Current index
  4. The array where reduce is currently called

Most of the time, you only need to use the first two parameters: the cumulative value and the current value.
Put aside these theories. Let’s take a look at a common example of reduce.

const numbers = [37, 12, 28, 4, 9]
const total = ((total, n) => total + n)
(total) // 90

During the first traversal, this accumulated value, that is, total, uses a value initialized to 37. It returns a value of 37 + n and n equals 12, so it gets 49. On the second traversal, the accumulated value is 49 and the return value is 49 + 28 = 77. Continue until the fourth time.

reduce is very powerful, you can actually use it to build many array methods, such as map or filter:

const map = (arr, fn) => {
 return ((mappedArr, element) => {
  return [...mappedArr, fn(element)]
 }, [])
}

(map([1, 2, 3, 4], n => n + 1)) // [2, 3, 4, 5]

const filter = (arr, fn) => {
 return ((filteredArr, element) => {
  return fn(element) ? [...filteredArr] : [...filteredArr, element]
 }, [])
}

(filter([1, 2, 3, 4, 5, 6], n => n % 2 === 0)) // [1, 3, 5]

Basically, we give reduce an initial default value []: our cumulative value. For map, we run a method, and the result is accumulated to the end, thanks to the expansion operator (no need to worry, discussed later). For filter, it's almost similar, except that we run the filter function on the element. If true, we return the previous array, otherwise the current element is added at the end of the array.

Let's look at a more advanced example: deep expansion array, that is, converting arrays like [1, 2, 3, [4, [[[5, [6, 7]]], 8]] into [1, 2, 3, 4, 5, 6, 7, 8].

function flatDeep(arr) {
 return ((flattenArray, element) => {
  return (element)
   ? [...flattenArray, ...flatDeep(element)]
   : [...flattenArray, element]
 }, [])
}

(flatDeep([1, 2, 3, [4, [[[5, [6, 7]]]], 8]])) // [1, 2, 3, 4, 5, 6, 7, 8]

This example is a bit like map, except that we use recursion. I don't want to explain this usage, it's beyond the scope of this article. However, if you want to learn more about recursion, please refer to this quality article.

Expand Operation (ES2015)

I know this is not a method. However, using the expand operation can help you do a lot when working with an array. In fact, you can use it in another array to expand the value of an array. From this point of view, you can copy an array, or concatenate multiple arrays.

const numbers = [1, 2, 3]
const numbersCopy = [...numbers]
(numbersCopy) // [1, 2, 3]

const otherNumbers = [4, 5, 6]
const numbersConcatenated = [...numbers, ...otherNumbers]
(numbersConcatenated) // [1, 2, 3, 4, 5, 6]

Note: The expansion operator made a shallow copy of the original array. But what is a shallow copy? 🤔

Well, shallow copy is to copy the original array as little as possible. When you have an array containing numbers, strings, or boolean values ​​(base types), they are OK and these values ​​are really copied. However, for objects and arrays, this is different. Only references to the original value will be copied! So if you create a shallow copy of an array containing objects and then modify the object in the copied array, it will also modify the objects of the original array because they are the same reference.

const arr = ['foo', 42, { name: 'Thomas' }]
let copy = [...arr]

copy[0] = 'bar'

(arr) // No mutations: ["foo", 42, { name: "Thomas" }]
(copy) // ["bar", 42, { name: "Thomas" }]

copy[2].name = 'Hello'

(arr) // /!\ MUTATION ["foo", 42, { name: "Hello" }]
(copy) // ["bar", 42, { name: "Hello" }]

So, if you want to "really" reliable a maintenance group that contains objects or arrays, you can use the lodash method cloneDeep. But don't feel like you have to do something like this. The goal here is to realize how things work.

The best thing to know

The methods you see below are the best idea to understand, and they can help you solve certain problems, such as searching for an element in an array, taking out part of the array or more.

includes(ES2015)

Have you ever tried using indexOf to find if something exists in an array? This is a bad way, right? Fortunately, include did this for us. Give include a parameter, and then search for it in the array, if an element exists.

const sports = ['football', 'archery', 'judo']
const hasFootball = ('football')
(hasFootball) // true

concat

The concat method can be used to merge two or more arrays.

const numbers = [1, 2, 3]
const otherNumbers = [4, 5, 6]

const numbersConcatenated = (otherNumbers)
(numbersConcatenated) // [1, 2, 3, 4, 5, 6]

// You can merge as many arrays as you want
function concatAll(arr, ...arrays) {
 return (...arrays)
}

(concatAll([1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12])) // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

forEach

Whenever you want to do something for each element of the array, you can use forEach. It uses a function as an argument and then gives it three arguments: current value, index, and current array.

const numbers = [1, 2, 3, 4, 5]
()
// 1 0 [ 1, 2, 3 ]
// 2 1 [ 1, 2, 3 ]
// 3 2 [ 1, 2, 3 ]

indexOf

This is used to find the index of the first discovered element in the given array. indexOf is also widely used to check if elements are in an array. But to be honest, I no longer use this now.

const sports = ['football', 'archery', 'judo']

const judoIndex = ('judo')
(judoIndex) // 2

find

The find method is very similar to the filter method. You must provide a function to test the elements of the array. However, once a find element is found to pass the test, it immediately stops testing other elements. Not used for filters, filter will iterate over the entire array, no matter what the situation is.

const users = [
 { id: 'af35', name: 'john' },
 { id: '6gbe', name: 'mary' },
 { id: '932j', name: 'gary' },
]

const user = (user =>  === '6gbe')
(user) // { id: '6gbe', name: 'mary' }

So use filter when you want to filter the entire array. Use find when you are sure to find a unique element in the array.

findIndex

This method is exactly the same as find except that it returns the index of the first discovered element, rather than directly returning the element.

const users = [
 { id: 'af35', name: 'john' },
 { id: '6gbe', name: 'mary' },
 { id: '932j', name: 'gary' },
]

const user = (user =>  === '6gbe')
(user) // 1

You might think that findIndex and indexOf are the same. Well…not exactly. The first element of indexOf is the base value (boolean, number, string, null, undefined or a symbol) and the first element of findIndex is a callback method.
So when you need to search for the basic value of an element in the array, use indexOf. If there are more complex elements, such as object, use findIndex.

slice

When you need to take out or copy a part of the array, you can use slice. But note that, like the expand operator, slice returns a shallow copy of the part!

const numbers = [1, 2, 3, 4, 5]
const copy = ()

I mentioned at the beginning of the article that looping is useless. Let's use an example of how you get rid of it.

Suppose you want to remove a certain amount of chat records from the API and display 5 of them. There are two ways to implement it: one is loop and the other is slice.

// Traditional way// Use loops to determine the number of messagesconst nbMessages =  < 5 ?  : 5
let messagesToShow = []
for (let i = 0; i < nbMessages; i++) {
 (posts[i])
}

// Assume that arr has less than 5 elements// slice will return the entire shallow copy of the original arrayconst messagesToShow = (0, 5)

some

If you want to test at least one element in the array passes the test, then you can use some. Just like map, filter, and find, some uses callback functions as parameters. It returns ture, if at least one element passes the test, return true otherwise returns false.
When you deal with permission issues, you can use some:

const users = [
 {
  id: 'fe34',
  permissions: ['read', 'write'],
 },
 {
  id: 'a198',
  permissions: [],
 },
 {
  id: '18aa',
  permissions: ['delete', 'read', 'write'],
 },
]

const hasDeletePermission = (user =>
 ('delete')
)
(hasDeletePermission) // true

every

Similar to some, the difference is that ever tests whether all elements meet the conditions (rather than at least one).

const users = [
 {
  id: 'fe34',
  permissions: ['read', 'write'],
 },
 {
  id: 'a198',
  permissions: [],
 },
 {
  id: '18aa',
  permissions: ['delete', 'read', 'write'],
 },
]

const hasAllReadPermission = (user =>
 ('read')
)
(hasAllReadPermission) // false

flat(ES2019)

This is an upcoming signature method in the JavaScript world. Generally speaking, flat penetrates a new array by combining all subarray elements. Accept a parameter, numeric type, which represents the depth you want to expand.

const numbers = [1, 2, [3, 4, [5, [6, 7]], [[[[8]]]]]]

const numbersflattenOnce = ()
(numbersflattenOnce) // [1, 2, 3, 4, Array[2], Array[1]]

const numbersflattenTwice = (2)
(numbersflattenTwice) // [1, 2, 3, 4, 5, Array[2], Array[1]]

const numbersFlattenInfinity = (Infinity)
(numbersFlattenInfinity) // [1, 2, 3, 4, 5, 6, 7, 8]

flatMap(ES2019)

Guess what this method does? I bet you can do it as the name suggests.

First run a mapping method on each element. Then display the data at one time. Very simple!

const sentences = [
 'This is a sentence',
 'This is another sentence',
 "I can't find any original phrases",
]

const allWords = (sentence => (' '))
(allWords) // ["This", "is", "a", "sentence", "This", "is", "another", "sentence", "I", "can't", "find", "any", "original", "phrases"]

In this example, there are some sentences in the array, but we want to get all the words. Instead of using map to split all sentences into words and then expand the array, you can use flatMap directly.
Not related to flatMap, you can use the reduce method to calculate the number of words (just show another usage of reduce)

const wordsCount = ((count, word) => {
 count[word] = count[word] ? count[word] + 1 : 1
 return count
}, {})
(wordsCount) // { This: 2, is: 2, a: 1, sentence: 2, another: 1, I: 1, "can't": 1, find: 1, any: 1, original: 1, phrases: 1, }

flatMap is often used for responsive programming, here is an example.

join

If you need to create strings based on array elements, join is exactly what you are looking for. It allows to create a new string by linking array elements, splitting by the provided splitter.

For example, you can use join to show the participants of the event at a glance:

const participants = ['john', 'mary', 'gary']
const participantsFormatted = (', ')
(participantsFormatted) // john, mary, gary

The following example is more realistic, in that you want to filter participants first and then get their names.

const potentialParticipants = [
 { id: 'k38i', name: 'john', age: 17 },
 { id: 'baf3', name: 'mary', age: 13 },
 { id: 'a111', name: 'gary', age: 24 },
 { id: 'fx34', name: 'emma', age: 34 },
]

const participantsFormatted = potentialParticipants
 .filter(user =>  > 18)
 .map(user => )
 .join(', ')

(participantsFormatted) // gary, emma

from

This is a static method that creates a new array from a class array, or iterates over the object like a string in the example. This method is very useful when dealing with dom.

 

const nodes = ('.todo-item') // This is a nodeList instanceconst todoItems = (nodes) // Now you can use map filter and so on, just like in an array!

Have you ever seen us using Array instead of array instances? This is what asked from is called a static method.

Then you can happily process these nodes, such as registering event listening on each node with forEach:

(item => {
 ('click', function() {
  alert(`You clicked on ${}`)
 })
})

It's best to understand mutations

Below are other common array methods. The difference is that they modify the original array. There is nothing wrong with modifying an array, it is best if you should consciously modify it.

For these methods, if you don't want to change the original array, you can only copy shallowly or deep copy before the operation.

const arr = [1, 2, 3, 4, 5]
const copy = [...arr] // or ()

sort

Yes, sort modified the original array. In fact, the array element sorting is done here. The default sort method converts all elements into strings and sorts them by the alphabet.

const names = ['john', 'mary', 'gary', 'anna']
()
(names) // ['anna', 'gary', 'john', 'mary']

If you have a Python background, be careful. Using sort will not get the result you want in a number array

const numbers = [23, 12, 17, 187, 3, 90]
()
(numbers) // [12, 17, 187, 23, 3, 90] 🤔。

So how to sort an array? Well, sort accepts a function and a comparison function. This function takes two parameters: the first element (we call it a) and the second element for comparison (b). The comparison between these two elements requires a number to be returned.

  1. If negative, a is sorted before b.
  2. If positive, b is sorted before a.
  3. If it is 0, nothing changes.

Then you can sort the array using the following method:

const numbers = [23, 12, 17, 187, 3, 90]
((a, b) => a - b)
(numbers) // [3, 12, 17, 23, 90, 187]

Or sort by recent time:

const posts = [
 {
  title: 'Create a Discord bot under 15 minutes',
  date: new Date(2018, 11, 26),
 },
 { title: 'How to get better at writing CSS', date: new Date(2018, 06, 17) },
 { title: 'JavaScript arrays', date: new Date() },
]
((a, b) =>  - ) // Substracting two dates returns the difference in millisecond between them
(posts)
// [ { title: 'How to get better at writing CSS',
//   date: 2018-07-17T00:00:00.000Z },
//  { title: 'Create a Discord bot under 15 minutes',
//   date: 2018-12-26T00:00:00.000Z },
//  { title: 'Learn Javascript arrays the functional way',
//   date: 2019-03-16T10:31:00.208Z } ]

fill

fill Modify or fill all elements of the array, using a static value from the start index to the end index. The most useful thing about fill is to fill a new array with static values.

// Normally I would have called a function that generates ids and random names but let's not bother with that here.
function fakeUser() {
 return {
  id: 'fe38',
  name: 'thomas',
 }
}

const posts = Array(3).fill(fakeUser())
(posts) // [{ id: "fe38", name: "thomas" }, { id: "fe38", name: "thomas" }, { id: "fe38", name: "thomas" }]

reverse

This method name is obvious here. However, like paying attention to sort , reverse reverses the position of the array.

const numbers = [1, 2, 3, 4, 5]

()
(numbers) // [5, 4, 3, 2, 1]

How you can replace

Finally, in this final part, you will find ways to change the original array while easily replacing some of them. I'm not saying you should abandon these methods. Just want you to realize that some array methods have side effects, and there are other options available here.

push

This is the most used method when processing arrays. In fact, push allows you to add one or more elements into an array. It also usually builds a new array based on an old array.

const todoItems = [1, 2, 3, 4, 5]

const itemsIncremented = []
for (let i = 0; i < ; i++) {
 (items[i] + 1)
}

(itemsIncremented) // [2, 3, 4, 5, 6]

const todos = ['Write an article', 'Proofreading']
('Publish the article')
(todos) // ['Write an article', 'Proofreading', 'Publish the article']

If you need to build an array like itemsIncremented, many methods are opportunities, like our friends map, filter or reduce. In fact, we can use map to do the same:

const itemsIncremented = (x => x + 1)

And if you need to use push, when you want to add new elements, expand the operator to support you.

const todos = ['Write an article', 'Proofreading']
([...todos, 'Publish the article']) // ['Write an article', 'Proofreading', 'Publish the article']

splice

splice is often used as a way to remove an index element. You can do the same with filter.

const months = ['January', 'February', 'March', 'April', ' May']

// With splice
(2, 1) // remove one element at index 2
(months) // ['January', 'February', 'April', 'May']

// Without splice
const monthsFiltered = ((month, i) => i !== 3)
(monthsFiltered) // ['January', 'February', 'April', 'May']

You might be wondering what if I need to remove multiple elements? Well, use slice:

const months = ['January', 'February', 'March', 'April', ' May']

// With splice
(1, 3) // remove thirds element starting at index 1
(months) // ['January', 'May']

// Without splice
const monthsFiltered = [...(0, 1), ...(4)]
(monthsFiltered) // ['January', 'May']

shift

shift Removes the first element of the array and returns it. Functionally, you can use spread/rest to implement it.

const numbers = [1, 2, 3, 4, 5]

// With shift
const firstNumber = ()
(firstNumber) // 1
(numbers) // [2, 3, 4, 5]

// Without shift
const [firstNumber, ...numbersWithoutOne] = numbers
(firstNumber) // 1
(numbersWithoutOne) // [2, 3, 4, 5]

unshift

Unshift allows you to add one or more elements at the beginning of the array. Like shift, you can do the same with the expansion operator:

const numbers = [3, 4, 5]

// With unshift
(1, 2)
(numbers) // [1, 2, 3, 4, 5]

// Without unshift
const newNumbers = [1, 2, ...numbers]
(newNumbers) // [1, 2, 3, 4, 5]

Too long to read the version:

  1. Whenever you operate on an array, don't use for-loop or repeat the wheels, what you want to do may already have a way out there.
  2. In most cases, you should use map, filter, reduce and expand operators. They are the most basic tools for developers.
  3. There are many ways to understand like slice, some, flatMap, etc. Remember them and use them when appropriate.
  4. Side effects lead to unwanted changes. Be clear about which methods will change your original array.
  5. slice and expand operators are shallow copies. Therefore, objects and subarrays will share the same reference, be careful to use them.
  6. The "old" method of changing the array can be replaced by the new one. It depends on what you want to do.

The above is the detailed explanation and integration of JavaScript arrays introduced by the editor. I hope it will be helpful to everyone. If you have any questions, please leave me a message and the editor will reply to everyone in time. Thank you very much for your support for my website!