给出EcmaScript第12.6.4节:
正在枚举的对象的属性可能会在列举。如果在访问期间尚未访问过的物业枚举被删除,将不会被访问。
但是,请检查此情况:
class Lead {
MAPPINGS = [
[
/Medication_Types_(\d+)/,
(data, key, acc, i) => {
const values = Object.keys(data)
.filter( key => /Medication_Types_(\d+)/.test(key ))
.map(key => data[key]);
console.log('the values: ', values);
acc['Medication_Types'] = values;
Object.keys(data).forEach( key => {
if( /Medication_Types_(\d+)/.test(key)) delete data[key];
})
return i;
}
]
]
format(data) {
const copy = JSON.parse(JSON.stringify(data));
let mapping = false;
let i = 1;
const result = Object.keys(copy).reduce((acc, key) => {
mapping = false;
this.MAPPINGS.forEach( (mapping) => {
if(mapping[0].test(key)){
mapping[1](copy, key, acc, i);
mapping = true;
}
});
if(!mapping){
acc[key] = copy[key];
}
return acc;
}, {});
return result;
}
}
const data = {
"Gender" : "Male",
"Medication_Types_1" : "A",
"Medication_Types_2" : "B",
"First_Name" : "bob"
}
const lead = new Lead();
const result = lead.format(data);
console.log('the result: ', result);
它输出:
the values: [ 'A', 'B' ]
the values: []
the result: {
Gender: 'Male',
Medication_Types: [],
Medication_Types_1: undefined,
Medication_Types_2: undefined,
First_Name: 'bob'
}
如果键被真正删除,那么“值”将不会第二次打印,而是我将得到(以及我想要的):
{
Gender: 'Male',
Medication_Types: ['A', 'B'],
First_Name: 'bob'
}
因此delete
似乎正在删除键,但不是从当前迭代中删除键,但是EcmaScript指出它将从当前迭代中删除!有什么问题,我该如何解决?
您未进行枚举。您正在创建一个数组,然后在该数组的forEach
迭代期间删除属性:
const keys = Object.keys(data);
console.log(keys); // at this point, all the keys are already in the array
keys.forEach( key => {
if( /Medication_Types_(\d+)/.test(key)) delete data[key];
})
当您从对象中delete
该属性时,不会将该属性从keys
数组中删除。