preface

You’ll learn about it in this article

  • Comparison of a use of the for loop with forEach/map/filter/find
  • A comparison of performance with for loops

If you are conditioned to know only for loops when it comes to loops, this is what you want to know

Requirement scenario: If the back end returns a JSON data format, as shown below, we need to get the array item in the returned object, or according to some specified conditions, take a specific value, and then render to the page, such as the name attribute value


  "ret":true."data": {"headerTitle":"Group member"."members": {"A":[
           {"id":"0A1"."name":"Small"."imgPhoto"."http://default.png"."phoneNumber": 18}, 1333344, "age" :]."B": []."C": []."D":[
           {"id":"0D1"."name":"Greatly"."imgPhoto"."http://default.png"."phoneNumber": 14343344,"age": 19}],"E": []."F": []."H":[
           {"id":"0H1"."name":"Huang huang"."imgPhoto"."http://default.png"."phoneNumber": 14343344}]."L":[
           {"id":"0L1"."name":"Little L1"."imgPhoto"."http://default.png"."phoneNumber": 14343344,"age": 20}, {"id":"0L2"."name":"Little L1"."imgPhoto"."http://default.png"."phoneNumber": 14343344,"age": 22} {"id":"0L3"."name":"Little L2"."imgPhoto"."http://default.png"."phoneNumber": 14343344,"age":21}]}}Copy the code

The result of the corresponding UI rendering is shown below

Target: Take the values in the object and loop through the array

Es5 implementation method: first through the object, the array object, and then for loop, to get the array item

Different framework code implements the way syntax behaves a little differently

Presents the

/ / array to iterate through arrays, obj said traversed each element, said the index through the array subscript, ng, of course, that provide ng - repeat instructions can also iterate over presents. The forEach (array, funciton (obj, index) {/ / dosomething }Copy the code

In the React

In React, the parent component passes values to the child component. Again, the map method is used most oftenCopy the code

V -for=”item in items”; v-for=”item in items

var members = {}; // Initialize an empty object to receive the object that the background is returning, and then use DOM(innerHTML, string concatenation) to fill the data in the specified position on the page. The following is the pseudo-code of axios.get()."/api/mock/linker.json")
.then(res=>{
  res = res.data;
  if(res.ret == true) {letdata = res.data; this.members = data.members; }})function showName() {for(key in this.members){
    for(var i=0; i<members[key].length; i++){for(j in members[key]){
       console.log(members[key][j].name)
      }
    }
  }
}

}
Copy the code

Here is a simple example of taking a value from an array of objects in the same format as the data above

var obj = {
"data": {"members": [{"id": 111,"name":"Gao"},
   {"id": 222,"name":"Xiao"},
   {"id": 333,"name":"Wang"} ] } } var newArrs= []; // Initialize an empty arrayfor( key in obj.data){
//console.log(obj.data[key]);
for(leti = 0; i<obj.data[key].length; i++){ console.log(obj.data[key][i]);for(j in obj.data[key][i]){
   console.log(obj.data[key][i].name);
   newArrs.push(obj.data[key][i].name);
   // break; As for why it's printed twice, because it's on the insidefor-in always has to go one time, and then jump to the topforLoop, plusbreakIf so, jump outfor}}} console.log(newArrs);}}} console.log(newArrs); / / (6) ["Gao"."Gao"."Xiao"."Xiao"."Wang"."Wang"] console.log(new Set(newArrs)); / / to heavy, {"Gao"."Xiao"."Wang"}
Copy the code

As shown in the following console

The forEach implementation

var obj = {
"data": {"members": [{"id": 111,"name":"Gao"},
{"id": 222,"name":"Xiao"},
{"id": 333,"name":"Wang"}
]
}
}
var newArrs= [];
 obj.data.members.forEach(function(member,index,originArrs){ newArrs.push(member.name); }) console.log(newArrs); / / /"Gao"."Xiao"."Wang"]

Copy the code

forEach

Function: Loop through each item in the number group, only through the number group

Writing:

Array object.foreach (function(1, 2, 3)){// do something,forEach returns undefined})Copy the code

The characteristics of

The callback function, which is executed for each element in the array, takes three arguments

  • The variable name 1 represents the value of the item in the array (the current item in the array)
  • The variable name 2 represents the index (the index of the current entry in the array)
  • The variable name 3 represents the original array (the array object itself)

Returns the value :undefined, always returns undefined, and cannot be chained

Usage scenarios

Email,QQ, shopping cart, list, select all: delete the selected mail, etc.,todolist, more than this

map

Function: Loop through each item in the number group, and only through the number group

writing

Map (callback(1, 2, 3){// do something to the array}Copy the code

The characteristics of

The map function is used in the same way as forEach, and the callback function receives parameters with the same meanings as forEach

It must have a return value. If you don’t give a return, it returns undefined

What is the value returned by return, which is equivalent to adding a new value to the new array, but it does not affect the original array, but makes a copy of the original array, and changes the copied items to support chained calls

Usage scenarios

Scenario 1: Copy the array and change something. Suppose you have an array (A) and double the values in A into B

Es5 writing

Var numbersA = [6]; var numbersB = [];for(var i = 0; i<numbersA.length; i++){ numbersB.push(numbersA[i]*2); } console.log(numbersB)Copy the code

To iterate through the array, we need to create a variable I that points to the length of the array (numbersa.length), and we need to define the counter modification (I ++), which is a very annoying error prone thing to do

When multiple layers of for loop are nested, not only is it hard to read, but the code is also hard to understand, and you have to keep track of every step in the for loop to make sure that every element in the array is traversed without missing anything

Iterator functions such as forEach and map avoid this problem and simplify the way Es6 maps are written

Var numbersA = [6]; var numbersB = [] var numbersC = numbersA.map(function(numberA,index,originArrs){
   returnnumbersB.push(numberA*2); } console.log(numbersA); / / [6] the console log (numbersB); // [2, 4, 6, 8, 10, 12] console.log(numbersC); // [1, 2, 3, 4, 5, 6] console.log(numbersC==numbersA) //false
Copy the code

Scenario 2: Get the properties of an array object in an array object

*/ var arrsA = [{name: {name:}}The word "apple",price:8888,city:"San Francisco"},
{name:"Gionee",price:1100,city:"Shenzhen"},
{name:"Millet",price:999,city:"Beijing"},
{name:"The hammer",price:888,city:"Shanghai"}
]
var sum = 0;
var prices = arrsA.map(function(item,index,arr){
console.log(item,index,arr);
returnitem.price; }); // It can also be called directly after this chain, followingforEach of the console. The log (prices); / / [8888110] 0999888 prices. ForEach (function(price,index,arr){ sum += price; }); console.log(sum); / / 11875Copy the code

filter

function

If the result is true, it returns a Boolean value. If it is false, it returns an empty array. It does not change the original array, but returns the new filtered array

writing

Array object.filter(function(currentVal,index,arrs){// do something}Copy the code

The characteristics of

The scope of elements that the filter function traverses is determined when the callback is first called

Elements added to the array after a call to filter are not traversed by the filter. If existing elements are changed, they are passed to the value at which the filter traversed them. Elements that are deleted or never assigned are not traversed, supporting chained calls

Usage scenarios

Scenario 1: Suppose you have an array of objects (A). Take the objects of the specified type from the array and place them in array B

Es5 implementation

*/ var persons = [{name: persons] */ var persons = [{name: persons]"Wang".type:"boy",city:"Guangxi",age:15,height:170},
{name:"Little beauty".type:"girl",city:"Beijing",age:16,height:180},
{name:"Gao".type:"girl",city:"Hunan",age:18,height:175},
{name:"Liu".type:"boy",city:"Hebei"Var persons = [],age:20,height:177}] var persons = [];for(var i = 0; i< persons.length; i++){if (persons[i].type == "boy"){ filterPersons.push(persons[i]); Persons [I]. Attribute name}} console.log(filterPersons);Copy the code

Filter implementation in Es6

var persons = [
{name:"Wang".type:"boy",city:"Guangxi",age:15,height:170},
{name:"Little beauty".type:"girl",city:"Beijing",age:16,height:180},
{name:"Gao".type:"girl",city:"Hunan",age:18,height:175},
{name:"Liu".type:"boy",city:"Hebei",age:20,height:177}
]

var filterPersons = persons.filter(function(person,index,arrs){
return person.type === "boy"; }) console.log(filterPersonstypeFor the entire object of boy, and shove it into a new arrayCopy the code

The console displays as follows

Scenario 2: Given an array (A, Persons), filter out objects that do not meet the following criteria

/* / select persons (age = 18, age = 20, height = 180) from persons (age = 18, age = 20, height = 180) from persons (age = 18, age = 20, height = 180) from persons (age = 18, age = 20, height = 180)"Wang".type:"boy",city:"Guangxi",age:15,height:170},
{name:"Little beauty".type:"girl",city:"Beijing",age:16,height:180},
{name:"Gao".type:"girl",city:"Hunan",age:18,height:175},
{name:"Liu".type:"boy",city:"Hebei",age:20,height:177}
]
var filterNum = persons.filter(function(person,index,arrs){
return person.type==="boy"&& person.age > 18 && person.age<=20 && person.height<180 }); console.log(filterNum); // [{name:"Liu".type: "boy", city: "Hebei", age: 20, height: 177}]
Copy the code

Scenario 3: Suppose there are two objects (A), filter out the data in array B that do not match the id value in object A (that is, extract the attributes in the object to be manipulated based on some condition)

/* Suppose there are two objects (A(info), B(languanges), */ var info = {id :4,content: {id :4,content: {id :4,content:"JavaScript"}

var languanges = [
{Id:4,content:"Angular4"},
{Id:2,content:"Vue.js",author:"Yuda"},
{Id:3,content:"Node.js"},
{Id:4,content:"React.js"}

]

var filterFun = function(info,languanges){
return languanges.filter(function(laguange){
returnlaguange.Id === info.Id; }) } console.log(filterFun(info,languanges)); // Select the languanges array with id equal to 4. If you want to retrieve a value from an object, support chained calls, directly following the map orforEach can beCopy the code

The following is a chained call

Var filterFun = var filterFun =function(info,languanges){
return languanges.filter(function(laguange){
return laguange.Id === info.Id;
}).map(function(currentVal){
return currentVal.content;
}).forEach(function(curr){
console.log(curr);
})
}
console.log(filterFun(info,languanges)

Copy the code

The filter method can sometimes be useful to filter out whether an object has an attribute value, return if it does, or return an empty array if it doesn’t, as shown below: Find an attribute that satisfies whether the Laguanges array object contains author

var filterFun = function(info,languanges){
return languanges.filter(function(laguange){
return laguange.hasOwnProperty("author");
})
}
console.log(filterFun(info,languanges))
Copy the code

find

Function:

It is used to look for the target element. If it is found, return the element. If it is not found, return undefined

writing

Find (callback(1, 2, 3)Copy the code

The callback also takes three arguments

  • The first argument, 1, represents the element currently traversed,
  • The second argument, 2, represents the index of the array elements searched for each iteration
  • The third argument, 3, represents the array of original operations

The characteristics of

After finding the first condition, there will be no further search, which is different from the filter filtering, find method is faster and more convenient

Return value: the matched option object is returned if the anonymous callback result is true, or undefined if it is false

Usage scenarios

Scenario 1: Given an array object (A), find the one that matches the criteria

Var learnWebs = [{name: segementDefault, name: segementDefault, name: segementDefault, name: segementDefault"segmentdefault"},
{name:"MDN"},
{name:"stackoverflow"},
{name:"v2ex"},
{name:"w3cplus"},
{name:"segmentdefault"}
]
var learnWeb = [];
for(var i = 0; i < learnWebs.length; i++){if(learnWebs[i].name === "segmentdefault"){
learnWeb.push(learnWebs[i]);
//break; / / if not addbreak", will go all over againfor}} console.log(learnWeb);Copy the code

Use find in Es6

Var learnWebs = [{name}} var learnWebs = [{name}}"segmentdefault"},
{name:"MDN"},
{name:"stackoverflow"},
{name:"v2ex"},
{name:"w3cplus"},
{name:"segmentdefault"}
]
newWebs = learnWebs.find(function(learnWeb,index,orginArrs){
return learnWeb.name ==="segmentdefault";
})
console.log(newWebs);
Copy the code

If a match is found in the iterator function, there is no further search. If the result is true, the object is returned. If the result is false, undefined is returned

Scenario 2

/ * assume that there are an array of objects (A), according to the conditions of the specified object to find qualified object in the array For example: news list goods list, blog posts, etc Found in the commodity list array object id, and then jump to the details page, click the id from one of an array object found in the object id, */ var goods = [{id:1,name: name]"Shoes",size:34,color:"red"},
{id:2,name:"Bag".type:"Hermes"},
{id:5,name:"Mobile phone".type:"iPhone6"}
]
var goodDetails = {id:5,desc:"This is the phone details page.",price:666}

function showDetailFun(goods,goodDetails){
return goods.find(function(good){
returngood.id===goodDetails.id; }) } console.log(showDetailFun(goods,goodDetails)); // For the corresponding UI interface, click the product list page on the left to enter the detailed page corresponding to the product (blog, news are similar to this).Copy the code

Performance comparison with for loops

This topic is easy to cause conflict, the author is not going to give a long introduction, the conclusion first, from two perspectives:

Performance :for loop >forEach> Map

Readability: forEach/map>for loop

ForEach /map/forEach/map/forEach/map/forEach/map/forEach/map/forEach/map/forEach/map/forEach/map/forEach/map

In general, it doesn’t make sense to talk about performance and efficiency, apart from business scenarios and ease of use, if the amount of data is not very large. Some of the array iterator methods added in Es5 and ES6 facilitate front-end development, making previously complex or verbose code readable and concise

And good for loop writing, in the case of large amount of data, indeed has better compatibility and multi-environment performance

You can test with console.time() and console.timeend (), but I think you should use the new iterator methods in Es5 and Es6. Having to define an initial value and keep track of the variables that count the loop are more likely to cause problems than for loops

Code is written for people to read and run on machines. From this point of view, I personally favor using the ITERator methods of Es5 and Es6, and sometimes in interviews, you will be asked for some performance comparisons

It’s boring, and it’s not about which one you use, but it’s more about testing the breadth of the interviewer’s knowledge

For more content, you can follow wechat itclanCoder public account, a transfer and sharing to bring you inspiration and wisdom useful account