介绍
数组是一种很重要的数据结构。那么我们如何遍历数组呢?
假如有这样一个数组。arr = [1,2,3,4,5,6,7],现在要遍历该数组。
以前我们可能会这样做:
for(var i=0;i<arr.length;i++){
console.log(arr[i]+"\n")
}
自ES5发布后,我们可以使用内置的forEach方法来遍历数组。
arr.forEach(function(val){
console.log(val+"\n")
})
这段代码看起来简单,然而有些缺陷,就是不能使用break语句中断循环,也不能使用return语句返回到外层函数。
于是我们很容易想到使用for-in来遍历数组
for(var index in arr){
console.log(typeof(index))//string
console.log(index + 1 +"\n") //打印依次是01 11 21 31 .....
}
然而这样也会有一点问题,在这段代码中,赋给 index 的值不是实际的数字,而是字符串“0”、 “1”、 “2”,此时很可能在无意之间进行字符串算数计算,例如:“2”+1==“21”,这给编码带来极大的不便。还有,在某些情况下,这段代码可能按照随机顺序遍历数组元素。
下面我的ES6方法登场了,就是使用for-of方法。
for(var val of arr){
console.log(val+"\n")
}
是不是很简洁,而且也不存在上述方法那样的缺陷。
forEech()
遍历每一项
let colors=["red","green","blue"];
colors.forEach(function(color){
console.log(color)
})
let numbers=[1,2,3,4,5];
let sum=0;
function addnum(num){
sum+=num;
}
numbers.forEach(addnum)
console.log(sum);
map()
map() 需要返回值,如果不给return,默认返回undefined;
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
map() 方法按照原始数组元素顺序依次处理元素。
场景1:假定有一个数值数组A,将A数组中的值以双倍的形式放到B数组
let nums=[1,2,3,4];
var numbes=nums.map(function(num){
return num * 2;
})
console.log(numbes)//[2, 4, 6, 8]
场景2:假定有一个对象数组A,将A数组中某对象属性存储到B数组中
let users=[
{name:"老蔡",age:"20"},
{name:"当东",age:"18"},
{name:"俊哥",age:"19"}
]
var age=users.map(function(us){
return us.age;
})
console.log(age)//["20", "18", "19"]
filter()
filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
场景1:假定有一个对象数组A,获取数组中指定类型的对象放到B数组中
let porducts=[
{name:"cucumber",type:"vegetable"},
{name:"banana",type:"fruit"},
{name:"celery",type:"vegetable"},
{name:"orange",type:"fruit"},
]
let filtered=porducts.filter(function(porduct){
return porduct.type === "fruit"
})
console.log(filtered);
场景2:假定有一个对象数组A,过滤掉不满足以下条件的对象
条件:蔬菜 数量大于0,价格小于10
let products=[
{name:"cucumber",type:"vegetable",quantity:0,price:1},
{name:"banana",type:"fruit",quantity:15,price:10},
{name:"celery",type:"vegetable",quantity:20,price:6},
{name:"orange",type:"fruit",quantity:5,price:4},
]
left product=products.filter(function(product){
return product.type === "vegetable"
&& product.quantity > 0
&& product.price < 10
})
console.log(product);
场景3:假定两个数组A,B,根据A中的id值过滤掉B中不符合的数据
let post={id:4,title:"javascript"};
let comments = [
{postId:4,content:"angular4"},
{postId:2,content:"vue.js"},
{postId:3,content:"node.js"},
{postId:4,content:"react.js"}
]
function commentsForPost(post,comments){
return comments.filter(function(comment){
return comment.postId === post.id;
})
}
console.log(commentsForPost(post,comments))
find()
find() 方法根据条件返回符合条件的对象,返回值不是数组
场景1:假定有一个对象数组A,找到符合条件的对象
let users=[
{name:"jill"},
{name:"alex"},
{name:"bill"}
]
let user=users.find(function(user){
return user.name === "alex";
})
console.log(user);//{name:"alex"}
场景2:假定有一个对象数组A,根据指定对象的条件找到数组中符合条件的对象
let posts=[
{id:1,title:"node.js"},
{id:2,title:"react.js"}
]
let comment={postId:2,content:"hello world"};
function commentForPost(post,comment){
return post.find(function(post){
return post.id === comment.postId;
})
}
console.log(commentForPost(posts,comment))//{id: 2, title: "react.js"}
every() && some()
场景1:计算对象数组中每个电脑的操作系统是否可用
every() 方法用于检测数组所有元素是否都符合指定条件(通过函数提供)。
every() 方法使用指定函数检测数组中的所有元素:
如果数组中检测到有一个元素不满足,则整个表达式返回 false ,且剩余的元素不会再进行检测。
如果所有元素都满足条件,则返回 true。
一假即假
var computers=[
{name:"apple",ram:32},
{name:"IBM",ram:4},
{name:"acer",ram:32}
]
var computer1=computers.every(function(computer){
return computer.ram > 16
})
console.log(computer1)//false
some() 作为一个用来检测数组是否满足一些条件的函数存在,同样是可以用作遍历的函数签名同forEach,有区别的是当任一callback返回值匹配为true则会直接返回true,如果所有的callback匹配均为false,则返回false。
some() 方法会依次执行数组的每个元素:
如果有一个元素满足条件,则表达式返回true , 剩余的元素不会再执行检测。
如果没有满足条件的元素,则返回false。
一真即真
var computers=[
{name:"apple",ram:32},
{name:"IBM",ram:4},
{name:"acer",ram:32}
]
var computer2=computers.some(function(computer){
return computer.ram > 16
})
console.log(computer2)//true
场景2:假定有一个注册页面,判断所有input内容的长度是否大于0
function Field(value){
this.value=value;
}
Field.prototype.validate=function(){
return this.value.length > 0;
}
var username= new Field("呼号");
var password= new Field("huhao");
var tel= new Field("1888888888");
var age= new Field("24");
console.log(username.validate());//true
var fields=[username,password,tel,age];
var formIsValidate=fields.every(function(field){
return field.validate();
})
console.log(formIsValidate)//true
reduce()
reduce() 方法接收一个函数作为累加器,数组中的每个值(从左到右)开始缩减,最终计算为一个值。
reduce() 可以作为一个高阶函数,用于函数的 compose。
注意: reduce() 对于空数组是不会执行回调函数的。
场景1:计算数组中所有值的总和
var numbers=[10,20,30];
var num=numbers.reduce(function(num,number){
return num+number;
},0)
console.log(num)//60
场景2:将数组中某个对象的属性抽离到另一个数组中
var primarycolors=[
{color:"red"},
{color:"yellow"},
{color:"blue"}
]
var colors=primarycolors.reduce(function(previous,primarycolor){
previous.push(primarycolor.color);
return previous;
},[])
console.log(colors);//["red", "yellow", "blue"]
场景3:判断字符串中字符串是否对称
function balanceParens(string){
return string.split("").reduce(function(previous,char){
if(char == "("){return ++previous};
if(char == ")"){return --previous};
return previous;
},0)
}
console.log(balanceParens("()()()(((())"))//2