写了这么久的react-native,但是最近却被一个js循环给难住了。
一、需求
有一个数组arr,长度不固定,而数组中存储的对象根据type不同分为两种,obj1和obj2,格式如下:
obj1 = {storeCode: '', storeNum: ''}
obj2 = {goodCode: '', goodName: '', goodNum: ''}
当type = 2时,arr = [obj1, obj1...],当type = 其他值时,arr = [obj2, obj2...],当我点击按钮时,会得到一个code,该code需要添加到数组的对象中(字段有值时不赋值,为空时才赋值,一个对象对应一个code)。
二、解决方案
解决方案当然是循环遍历了,但是方案一却怎么也实现不了,添加标记之类的也不好使,总有bug,后来使用方案二完美解决。
方案一:使用.map()方法循环遍历
大体思路:当checkType ==2时,dataSource[currentIndex].findOther = [obj1, obj1...],得到的code需要按顺序添加到数组的obj中,当dataSource[currentIndex].findOther[0].storeHouseCode === ''时,code要赋值给storeHouseCode,并结束循环;当dataSource[currentIndex].findOther[0].storeHouseCode !== ''时,便要循环数组的下一个对象进行判断,直到找到storeHouseCode === '',将code赋值给storeHouseCode,结束循环;当checkType !==2时,dataSource[currentIndex].findOther = [obj2, obj2...],当dataSource[currentIndex].findOther[0].skuCode === ''时,code要赋值给skuCode,并结束循环,当dataSource[currentIndex].findOther[0].skuCode !== ''时便要循环数组的下一个对象进行判断,直到找到skuCode === '',将code赋值给skuCode,结束循环。
上代码:
// 接收PDA扫描数据
this.logListener = NativeAppEventEmitter.addListener('scannerCode', (code) => {
const checkType = this.props.navigation.state.params.checkType;
const {currentIndex, dataSource} = this.state;
console.log('scannerCode', code);
dataSource[currentIndex].findOther.map((item, index) => {
if (checkType == 2) {
if (item.storeHouseCode === '') {
let data = {
storeHouseCode: code,
batchBornNumberFlag: dataSource[currentIndex].batchBornNumberFlag,
batchBornTimeFlag: dataSource[currentIndex].batchBornTimeFlag,
batchInvalidTimeFlag: dataSource[currentIndex].batchInvalidTimeFlag,
batchNumberFlag: dataSource[currentIndex].batchNumberFlag,
batchSkuGoodFlag: dataSource[currentIndex].batchSkuGoodFlag,
batchSupplierFlag: dataSource[currentIndex].batchSupplierFlag,
};
dataSource[currentIndex].findOther.splice(i, 1, {...dataSource[currentIndex].findOther[i], ...data});
this.setState({dataSource});
}
} else {
if (item.skuCode === '') {
this.props._getSkuName({
skuName: code,
warehouseCode: dataSource[currentIndex].warehouseCode,
}, (result) => {
if (result) {
let data = {
skuCode: result.skuCode,
skuName: result.skuName
};
dataSource[currentIndex].findOther.splice(index, 1, {...dataSource[currentIndex].findOther[index], ...data});
this.setState({dataSource})
} else {
let data = {
skuCode: code,
};
dataSource[currentIndex].findOther.splice(index, 1, {...dataSource[currentIndex].findOther[index], ...data});
this.setState({dataSource});
Toast.show('未查询到该商品');
}
})
}
}
})
});
方案二:使用for循环遍历
大体思路同上。
上代码:
// 接收PDA扫描数据
this.logListener = NativeAppEventEmitter.addListener('scannerCode', (code) => {
const checkType = this.props.navigation.state.params.checkType;
const {currentIndex, dataSource} = this.state;
console.log('scannerCode', code);
if (dataSource[currentIndex].findOther.length > 0) {
if (checkType == 2) { // type
for (let i = 0; i < dataSource[currentIndex].findOther.length; i++) {
if (dataSource[currentIndex].findOther[i].storeHouseCode === '') { //code
let data = {
storeHouseCode: code,
batchBornNumberFlag: dataSource[currentIndex].batchBornNumberFlag,
batchBornTimeFlag: dataSource[currentIndex].batchBornTimeFlag,
batchInvalidTimeFlag: dataSource[currentIndex].batchInvalidTimeFlag,
batchNumberFlag: dataSource[currentIndex].batchNumberFlag,
batchSkuGoodFlag: dataSource[currentIndex].batchSkuGoodFlag,
batchSupplierFlag: dataSource[currentIndex].batchSupplierFlag,
};
dataSource[currentIndex].findOther.splice(i, 1, {...dataSource[currentIndex].findOther[i], ...data});
this.setState({dataSource});
break; // 跳出循环
}
}
} else {
for (let index = 0; index < dataSource[currentIndex].findOther.length; index++) {
if (dataSource[currentIndex].findOther[index].skuCode === '') { // code
this.props._getSkuName({
skuName: code,
warehouseCode: dataSource[currentIndex].warehouseCode,
}, (result) => {
if (result) {
let data = {
skuCode: result.skuCode,
skuName: result.skuName
};
dataSource[currentIndex].findOther.splice(index, 1, {...dataSource[currentIndex].findOther[index], ...data});
this.setState({dataSource})
} else {
let data = {
skuCode: code,
};
dataSource[currentIndex].findOther.splice(index, 1, {...dataSource[currentIndex].findOther[index], ...data});
this.setState({dataSource});
Toast.show('未查询到该商品');
}
});
break; // 跳出循环
}
}
}
}
});
总结
map() 方法按照原始数组元素顺序依次处理元素,map方法的作用就是原数组被“映射”成对应新数组,map会返回一个新数组,不对原数组产生影响,因为返回数组所以可以链式操作。如果要跳出循坏,还是用for循环。
综上所述,.map()不适合用来解决上述问题。