在做购物车结算的时候,使用filter对购物车商品数组过滤选中商品,对单个数组十分简单,如:
list:[
{
id:0,
check:false
},
{
id:1,
check:true
}
]
const arry = this.list.filter(function(item) {
return item.check === true;
})
console.log(arry); //list:[{id:1,check:true}]
但是当数组为多维数组时,这样?:
goodlist:[
{
shopID:0,
good:[
{
goodsID:1001,
goodsName:'上衣',
select:false
}
]
},
{
shopID:1,
good:[
{
goodsID:1011,
goodsName:'鞋子',
select:true
},
{
goodsID:1002,
goodsName:'袜子',
select:false
}
]
}
]
const payArry=this.goodlist.filter(function(item){
return item.good.filter(function(item1){
return item1.select===true
})
})
双重return?我们的第一反应肯定是这样做,但是很显然不行,返回的结果是全部数据。
当你的购物车为单一商品,即每个商品独立开来,不是以店铺为模块时,可使用:
const payArry=this.goodlist.filter(function(item){
return item.good[0].select===true
})
因为它只能拿到数组指定位置的数据,那一个模块多个商品怎么办呢?我用的是遍历数组,但在这有几个问题:
var arry=[]
//过滤出选中的商品
this.goodlist.forEach((shopGoods,index)=>{//店铺商品,索引
arry[index]=shopGoods
arry[index].good=shopGoods.good.filter(function(item){
return item.select===true
})
})
console.log(arry);
问题1:对多维数组内部数组进行过滤时 ,过滤了未选中商品,但该商品的店铺头还在,导致该对象长度不为空。
我的解决方法:对该结果进行二次过滤
//过滤掉没有选中商品的店铺
const payArry=shopcartGoods.filter(function(item){
return item.good.length!=0
})
onsole.log(payArry);
问题2:对数组进行过滤时,尽管新定义了新数组,但是因为指向的是同一地址,原数组也跟着改变了。
如:
//普通数组,未切断关联时,改变b的值,a也跟着改变
var a = [1];
var b= [];
b = a;
b[1]=2;
console.log(a);//a=[1,2]
console.log(b);//b=[1,2]
要实现改变b数组而不改变a数组,就得进行深拷贝,使用扩展运算符…进行复制,或者是用concat或者slice赋值。
var b = [...a];
//var b = [].concat[a];
//var b = a.slice();
b[1]=2;
console.log(a);//a=[1]
console.log(b);//b=[1,2]
但这种方法只适用于普通数组,当数组类型是[Object(Array)]类型时,仍会影响原数组。所以购物车结算时我用循环创建出新数组:
//过滤出选中的商品
var arry =[]
this.goodlist.forEach((shopGoods,index)=>{//店铺商品,索引
var cart=[]
cart.push(shopGoods)
arry[index]=cart
// arry[index]=shopGoods
arry[index].good=shopGoods.good.filter(function(item){
if(item.select===true){
arry[index].storeName=shopGoods.storeName
}
return item.select===true
})
})
// console.log(arry);
//过滤掉没有选中商品的店铺
const payArry=arry.filter(function(item){
return item.good.length!=0
})
console.log(payArry);
后续更改:
//过滤出选中的商品
var isgoods=true; //商品数量是否存在为空值(商品数为可输入,可能为空)
var payArry=[] //准备结算的商品列表
this.goodlist.forEach((shopGoods,index)=>{//店铺商品,索引
var arry ={}// 确保每次循环都创建一个新对象
var a=[].concat(shopGoods)
console.log(a);
var good=a[0].good.filter(function(item){
console.log(item);
if(item.select===true){
if(item.goodnum==''){
isgoods=false //选中的商品数量有为空的
return ;
}
let storeName='storeName'
arry[storeName]=a[0].storeName
}
return item.select===true
})
if(good.length!=0){
let goods='goods'
arry[goods]=good
payArry.push(arry)
}
})
console.log(payArry);
console.log("最后结算的数据: " + JSON.stringify(payArry));
if (payArry.length == 0 || isgoods==false) {
uni.showToast({
title: "您还没有选中要结算的商品或商品数量为空",
icon: "none"
});
return
}