JavaScript-基于空单元格对CSV字段进行分组



我有来自CSV文件的数据,该文件可以有空白字段,并且必须根据该字段对数据进行分组。

下面是一个按位置划分的人员数据的简单示例。位置数据只出现在第一个人身上,以下每个没有分配位置的人都属于之前的位置:

"Objects:", [{
location: "New York",
date: "10/10/2021",
name: "Max",
surname: "Payne"
}, {
location: "",
date: "",
name: "Duke",
surname: "Nuken"
}, {
location: "",
date: "",
name: "Jack",
surname: "Carver"
}, {
location: "Las Vegas",
date: "30/10/2021",
name: "Leon",
surname: "Kennedy"
}, {
location: "",
date: "",
name: "Donkey",
surname: "Kong"
}, {
location: "",
date: "",
name: "Ryu",
surname: "Hayabusa"
}]

我需要将人员列表加入到一个列表中,并将其添加到相应的位置:

"Objects:", [{
location: "New York",
date: "10/10/2021",
persons: [{
name: "Max",
surname: "Payne"
}, {
name: "Duke",
surname: "Nuken"
}, {
name: "Jack",
surname: "Carver"
}]
}, {
location: "Las Vegas",
date: "30/10/2021",
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, date, 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", "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"],],
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, null, 2));
.as-console-wrapper { max-height: 100% !important; top: 0; }

最新更新