【问题标题】:JavaScript - Group CSV fields based on empty cellsJavaScript - 基于空单元格对 CSV 字段进行分组
【发布时间】:2021-05-14 20:42:47
【问题描述】:

我有来自 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})
      , {}
   ));

什么是解决这个问题的好方法?

【问题讨论】:

    标签: javascript arrays algorithm csv javascript-objects


    【解决方案1】:

    这是一个使用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; }

    【讨论】:

    • 这很好!不幸的是,在我的用例中,我相信标题可能会有所不同,例如,我可以拥有人的出生日期或年龄,或者在城市中拥有更多的其他字段。
    猜你喜欢
    • 2021-12-14
    • 2013-03-27
    • 2014-10-02
    • 2018-01-18
    • 1970-01-01
    • 2011-11-27
    • 1970-01-01
    • 2021-08-31
    • 1970-01-01
    相关资源
    最近更新 更多