
map , filter , reduce and spread operator. They are effective and helpful.map method. In general, every time you need to change the elements of an array, consider this option. const numbers = [1, 2, 3, 4] const numbersPlusOne = numbers.map(n => n + 1) console.log(numbersPlusOne) // [2, 3, 4, 5] const allActivities = [ { title: 'My activity', coordinates: [50.123, 3.291] }, { title: 'Another activity', coordinates: [1.238, 4.292] } ] const allCoordinates = allActivities.map(activity => activity.coordinates) console.log(allCoordinates) // [[50.123, 3.291], [1.238, 4.292]] map , filter takes as its only parameter a function that is called on each element of the array. This function should return a boolean value:true if you want to keep the element in an array;false - if you do not want to save it. const numbers = [1, 2, 3, 4, 5, 6] const oddNumbers = numbers.filter(n => n % 2 !== 0) console.log(oddNumbers) // [1, 3, 5] const participants = [ { id: 'a3f47', username: 'john' }, { id: 'fek28', username: 'mary' }, { id: 'n3j44', username: 'sam' }, ] function removeParticipant(participants, id) { return participants.filter(participant => participant.id !== id) } console.log(removeParticipant(participants, 'a3f47')) // [{ id: 'fek28', username: 'mary' }, { id: 'n3j44', username: 'sam' }]; reduce method takes an array of values and combines them into one value. It takes two parameters, a callback function (which is a gearbox ) and an optional initial value (which is the first element of the array by default). The gearbox itself takes four parameters:reduce method was called.reduce . const numbers = [37, 12, 28, 4, 9] const total = numbers.reduce((total, n) => total + n) console.log(total) // 90 reduce method is so functional that you can use it to build a variety of array methods like map or filter . const map = (arr, fn) => { return arr.reduce((mappedArr, element) => { return [...mappedArr, fn(element)] }, []) } console.log(map([1, 2, 3, 4], n => n + 1)) // [2, 3, 4, 5] const filter = (arr, fn) => { return arr.reduce((filteredArr, element) => { return fn(element) ? [...filteredArr] : [...filteredArr, element] }, []) } console.log(filter([1, 2, 3, 4, 5, 6], n => n % 2 === 0)) // [1, 3, 5] [] to the reduce method, the battery. For map we run a function, the result of which is added to the end of the battery using the spread operator (we’ll talk about it below, do not worry). For filter do almost the same thing, only we run the filter function on the element. If it is true, we return the previous array. Otherwise, add the element to the end of the array.[1, 2, 3, [4, [[[5, [6, 7]]]], 8]] to [1, 2, 3, 4, 5, 6, 7, 8] . function flatDeep(arr) { return arr.reduce((flattenArray, element) => { return Array.isArray(element) ? [...flattenArray, ...flatDeep(element)] : [...flattenArray, element] }, []) } console.log(flatDeep([1, 2, 3, [4, [[[5, [6, 7]]]], 8]])) // [1, 2, 3, 4, 5, 6, 7, 8] map , except that we use recursion here. I will not dwell on recursion in detail, because it goes beyond our theme, but if you want to learn more, go to this great resource . const numbers = [1, 2, 3] const numbersCopy = [...numbers] console.log(numbersCopy) // [1, 2, 3] const otherNumbers = [4, 5, 6] const numbersConcatenated = [...numbers, ...otherNumbers] console.log(numbersConcatenated) // [1, 2, 3, 4, 5, 6] const arr = ['foo', 42, { name: 'Thomas' }] let copy = [...arr] copy[0] = 'bar' console.log(arr) // No mutations: ["foo", 42, { name: "Thomas" }] console.log(copy) // ["bar", 42, { name: "Thomas" }] copy[2].name = 'Hello' console.log(arr) // /!\ MUTATION ["foo", 42, { name: "Hello" }] console.log(copy) // ["bar", 42, { name: "Hello" }] indexOf to find out if there is an element in an array or not? A terrible way to check, right?includes method does the checking for us. Specify the parameter for includes, and it will search the item by array. const sports = ['football', 'archery', 'judo'] const hasFootball = sports.includes('football') console.log(hasFootball) // true const numbers = [1, 2, 3] const otherNumbers = [4, 5, 6] const numbersConcatenated = numbers.concat(otherNumbers) console.log(numbersConcatenated) // [1, 2, 3, 4, 5, 6] // You can merge as many arrays as you want function concatAll(arr, ...arrays) { return arr.concat(...arrays) } console.log(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 method. It takes a function as a parameter, which, in turn, also takes three parameters: the current value, the index, and the array. const numbers = [1, 2, 3, 4, 5] numbers.forEach(console.log) // 1 0 [ 1, 2, 3 ] // 2 1 [ 1, 2, 3 ] // 3 2 [ 1, 2, 3 ] indexOf often check the presence of an element in the array. Honestly, now I use it infrequently. const sports = ['football', 'archery', 'judo'] const judoIndex = sports.indexOf('judo') console.log(judoIndex) // 2 find method is similar to filter . You need to provide it with a function that tests each element of the array. However, find stops testing elements as soon as it finds one that passed the test. This is not a filter that iterates over the entire array, regardless of the circumstances. const users = [ { id: 'af35', name: 'john' }, { id: '6gbe', name: 'mary' }, { id: '932j', name: 'gary' }, ] const user = users.find(user => user.id === '6gbe') console.log(user) // { id: '6gbe', name: 'mary' } filter method when you want to filter the entire array, and the find method when you are sure that you are looking for a unique element in the array.find , but it returns the index of the first element found instead of the element itself. const users = [ { id: 'af35', name: 'john' }, { id: '6gbe', name: 'mary' }, { id: '932j', name: 'gary' }, ] const user = users.findIndex(user => user.id === '6gbe') console.log(user) // 1 findIndex and indexOf are the same thing. Not really. The first parameter of indexOf is a primitive value (boolean, number, string, undefined value, or character), while the first parameter findIndex is a callback function.indexOf . If you have more complex elements, such as objects, use findIndex .slice method. But be careful: as the spread operator, slice returns a shallow copy . const numbers = [1, 2, 3, 4, 5] const copy = numbers.slice() slice method. // The "traditional way" to do it: // Determine the number of messages to take and use a for loop const nbMessages = messages.length < 5 ? messages.length : 5 let messagesToShow = [] for (let i = 0; i < nbMessages; i++) { messagesToShow.push(posts[i]) } // Even if "arr" has less than 5 elements, // slice will return an entire shallow copy of the original array const messagesToShow = messages.slice(0, 5) some . Like map , filter or find , the some method takes a callback function as the only parameter, and then returns true if at least one element passes the test, and false if not.some suitable for working with permissions. const users = [ { id: 'fe34', permissions: ['read', 'write'], }, { id: 'a198', permissions: [], }, { id: '18aa', permissions: ['delete', 'read', 'write'], } ] const hasDeletePermission = users.some(user => user.permissions.includes('delete') ) console.log(hasDeletePermission) // true some , except that it checks that each element (and not one ) matches the condition. const users = [ { id: 'fe34', permissions: ['read', 'write'], }, { id: 'a198', permissions: [], }, { id: '18aa', permissions: ['delete', 'read', 'write'], } ] const hasAllReadPermission = users.every(user => user.permissions.includes('read') ) console.log(hasAllReadPermission) // false flat creates a new array, connecting all the elements of the nested array. It takes one parameter — a number that indicates how much you want to reduce the dimension of the array. const numbers = [1, 2, [3, 4, [5, [6, 7]], [[[[8]]]]]] const numbersflattenOnce = numbers.flat() console.log(numbersflattenOnce) // [1, 2, 3, 4, Array[2], Array[1]] const numbersflattenTwice = numbers.flat(2) console.log(numbersflattenTwice) // [1, 2, 3, 4, 5, Array[2], Array[1]] const numbersFlattenInfinity = numbers.flat(Infinity) console.log(numbersFlattenInfinity) // [1, 2, 3, 4, 5, 6, 7, 8] const sentences = [ 'This is a sentence', 'This is another sentence', "I can't find any original phrases", ] const allWords = sentences.flatMap(sentence => sentence.split(' ')) console.log(allWords) // ["This", "is", "a", "sentence", "This", "is", "another", "sentence", "I", "can't", "find", "any", "original", "phrases"] map method and dividing all sentences into words, and then shortening the array, you can immediately use flatMap .reduce function (this does not apply to flatMap , I just want to show you another example of using the reduce method). const wordsCount = allWords.reduce((count, word) => { count[word] = count[word] ? count[word] + 1 : 1 return count }, {}) console.log(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 method flatMap also often used in reactive programming. An example you can see here .join method is what you need. It allows you to create a new line, connecting all the elements of the array, separated by the provided separator.join you can visually display all participants in the activity. const participants = ['john', 'mary', 'gary'] const participantsFormatted = participants.join(', ') console.log(participantsFormatted) // john, mary, gary 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 => user.age > 18) .map(user => user.name) .join(', ') console.log(participantsFormatted) // gary, emma const nodes = document.querySelectorAll('.todo-item') // this is an instance of NodeList const todoItems = Array.from(nodes) // now, you can use map, filter, etc. as you're workin with an array! forEach method. todoItems.forEach(item => { item.addEventListener('click', function() { alert(`You clicked on ${item.innerHTML}`) }) }) const arr = [1, 2, 3, 4, 5] const copy = [...arr] // or arr.slice() sort changes the original array. In fact, it sorts the elements of the array in place. The default sort method transforms all elements into strings and sorts them alphabetically. const names = ['john', 'mary', 'gary', 'anna'] names.sort() console.log(names) // ['anna', 'gary', 'john', 'mary'] sort method when working with an array of numbers will not give you the desired result. const numbers = [23, 12, 17, 187, 3, 90] numbers.sort() console.log(numbers) // [12, 17, 187, 23, 3, 90] sort method takes one function - the comparison function . It takes two parameters: the first element ( ) and the second element for comparison ( b ). A comparison between these two elements requires the return of a digit:a sorted before b ;b sorted before a ; const numbers = [23, 12, 17, 187, 3, 90] numbers.sort((a, b) => a - b) console.log(numbers) // [3, 12, 17, 23, 90, 187] 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() }, ] posts.sort((a, b) => a.date - b.date) // Substracting two dates returns the difference in millisecond between them console.log(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 method changes or fills all elements of an array from the initial index to the final one with the specified value. An example of excellent use of fill is to fill a new array with initial data. // 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()) console.log(posts) // [{ id: "fe38", name: "thomas" }, { id: "fe38", name: "thomas" }, { id: "fe38", name: "thomas" }] const numbers = [1, 2, 3, 4, 5] numbers.reverse() console.log(numbers) // [5, 4, 3, 2, 1] const messages = ['Hello', 'Hey', 'How are you?', "I'm fine"] const lastMessage = messages.pop() console.log(messages) // ['Hello', 'Hey', 'How are you?'] console.log(lastMessage) // I'm fine const todoItems = [1, 2, 3, 4, 5] const itemsIncremented = [] for (let i = 0; i < items.length; i++) { itemsIncremented.push(items[i] + 1) } console.log(itemsIncremented) // [2, 3, 4, 5, 6] const todos = ['Write an article', 'Proofreading'] todos.push('Publish the article') console.log(todos) // ['Write an article', 'Proofreading', 'Publish the article'] itemsIncremented method, there are suitable for this and already familiar to us map , filter or reduce . For example, we can take a map to do this. const itemsIncremented = todoItems.map(x => x + 1) push when you need to add a new element, then the spread operator comes in handy. const todos = ['Write an article', 'Proofreading'] console.log([...todos, 'Publish the article']) splice often referenced to remove an element on a specific index. You can do the same with the filter method. const months = ['January', 'February', 'March', 'April', ' May'] // With splice months.splice(2, 1) // remove one element at index 2 console.log(months) // ['January', 'February', 'April', 'May'] // Without splice const monthsFiltered = months.filter((month, i) => i !== 3) console.log(monthsFiltered) // ['January', 'February', 'April', 'May'] slice . const months = ['January', 'February', 'March', 'April', ' May'] // With splice months.splice(1, 3) // remove thirds element starting at index 1 console.log(months) // ['January', 'February', 'April', 'May'] // Without splice const monthsFiltered = [...months.slice(0, 1), ...months.slice(4)] console.log(monthsFiltered) // ['January', 'February', 'April', 'May'] shift method removes the first element of the array and returns it. To do this in the style of functional programming, you can use the spread or rest operator. const numbers = [1, 2, 3, 4, 5] // With shift const firstNumber = numbers.shift() console.log(firstNumber) // 1 console.log(numbers) // [2, 3, 4, 5] // Without shift const [firstNumber, ...numbersWithoutOne] = numbers console.log(firstNumber) // 1 console.log(numbersWithoutOne) // [2, 3, 4, 5] shift , you can do this with the spread operator. const numbers = [3, 4, 5] // With unshift numbers.unshift(1, 2) console.log(numbers) // [1, 2, 3, 4, 5] // Without unshift const newNumbers = [1, 2, ...numbers] console.log(newNumbers) // [1, 2, 3, 4, 5] map , filter , reduce and the spread operator - these are important tools for any developer.slice , some , flatMap , . . .slice spread . — .Source: https://habr.com/ru/post/446902/
All Articles