问题描述
我有来自 CSV 文件的数据,该文件可以包含空白字段,并且必须基于此对数据进行分组。
以下是按位置划分的人员数据的简单示例。位置数据仅针对第一个人显示,之后没有分配位置的每个人都属于之前的位置:
"Objects:",[{
location: "New York",date: "10/10/2021",name: "Max",surname: "Payne"
},{
location: "",date: "",name: "Duke",surname: "Nuken"
},name: "Jack",surname: "Carver"
},{
location: "Las Vegas",date: "30/10/2021",name: "Leon",surname: "Kennedy"
},name: "Donkey",surname: "Kong"
},name: "Ryu",surname: "Hayabusa"
}]
"Objects:",persons: [{
name: "Max",surname: "Payne"
},{
name: "Duke",surname: "Nuken"
},{
name: "Jack",surname: "Carver"
}]
},persons: [{
name: "Leon",surname: "Kennedy"
},{
name: "Donkey",surname: "Kong"
},{
name: "Ryu",surname: "Hayabusa"
}]
}]
数据最初以这种形式的数组数组形式出现:
const [headers,...lines] = [
["location","date","name","surname" ],["New York","10/10/2021","Max","Payne" ],["","","Duke","Nuken" ],"Jack","Carver" ],["Las Vegas","30/10/2021","Leon","Kennedy" ],"Donkey","Kong" ],"Ryu","Hayabusa"],];
我目前必须将数组转换为这个问题中的第一个对象列表的代码是这样的:
const locations = lines.map( (line) =>
line.reduce((object,value,index) =>
({...object,[ headers[index] ]: value}),{}
));
解决方法
这是一个使用 Array#reduce()
并硬编码标头名称的示例。
const
[headers,...lines] = [["location","date","name","surname"],["New York","10/10/2021","Max","Payne"],["","","Duke","Nuken"],"Jack","Carver"],["Las Vegas","30/10/2021","Leon","Kennedy"],"Donkey","Kong"],"Ryu","Hayabusa"],],result = lines.reduce((a,[location,date,name,surname]) => {
if (location && date) a.push({ location,persons: [] });
a[a.length - 1].persons.push({ name,surname });
return a;
},[]);
console.log(JSON.stringify(result,null,2));
.as-console-wrapper { max-height: 100% !important; top: 0; }
这是一个更动态的示例,允许您指定应该存在以供分组的“requiredIndeces”。您可以根据自己的特定需求进行调整。
const
input = [["location",refactorCSV = (arr,requiredIndeces) => {
const
reduceByRequiredIndex = (arr) => arr.reduce((a,x,i) =>
(a[+requiredIndeces.includes(i)].push(x),a),[[],[]]),[headers,...lines] = arr,[entryProps,requiredProps] = reduceByRequiredIndex(headers);
return lines.reduce((a,line) => {
const [personValues,requiredValues] = reduceByRequiredIndex(line);
if (requiredValues.every(v => v !== '')) {
const required = {};
requiredProps.forEach((prop,i) => required[prop] = requiredValues[i]);
a.push({ ...required,persons: [] });
}
const person = {};
entryProps.forEach((prop,i) => person[prop] = personValues[i]);
a[a.length - 1].persons.push(person);
return a;
},[]);
},result = refactorCSV(input,[0,1]);
console.log(JSON.stringify(result,2));
.as-console-wrapper { max-height: 100% !important; top: 0; }