代码之家  ›  专栏  ›  技术社区  ›  Hussain Ali Akbar

一种将数组转换为对象数组的有效方法

  •  1
  • Hussain Ali Akbar  · 技术社区  · 6 年前

    我有一个接受两个参数的函数: 阵列

    ["id","name","age",...]
    

    和另一个数组 暗礁 其中包含这些字段的数据:

     [["1", "john", "10"],["2", "Jane", "11"],["3", "John Doe", "12"],...]
    

    [{id: "1", name: "john", age: "10"},{id: 2", name: "jane", age: "11"},{id: "3", name: "John doe", age: "12"}, ...]
    

    功能如下:

    const arrayOfArraysToArrayOfObjects = (csvFields, csvRows) => {
            const data = csvRows.map((row) => {
                let obj = {};
                csvFields.forEach((field, index) => {
                    obj[field] = row[index];
                });
                return obj;
            });
            return data;
        };
    
    
        const csvFields = ["id","name","age"];
        const csvRows = [["1", "john", "10"],["2", "Jane", "11"],["3", "John Doe", "12"]];
        const data = arrayOfArraysToArrayOfObjects(csvFields, csvRows);
        console.log(data);

    问题是,这个函数不是很有效,而且在处理包含很多行的大型csv文件时会变得非常慢。此外,字段可以根据不同的csv文件而变化,这就是为什么我必须保持它的动态性。

    有什么办法使这个功能更有效吗?

    谢谢你的帮助!

    3 回复  |  直到 6 年前
        1
  •  2
  •   Илья Зелень    6 年前

    周期比方法快,请参见基准: https://jsperf.com/my-test321321321

    const arrayOfArraysToArrayOfObjects = (csvFields, csvRows) => {
      let res = []
    
      for (let arr of csvRows) {
        let obj = {}
        for (let i = 0; i < arr.length; i++) {
          obj[csvFields[i]] = arr[i]
    
        }
        res.push(obj)
      }
    
      return res;
    };
    
    
    const csvFields = ["id","name","age"];
    const csvRows = [["1", "john", "10"],["2", "Jane", "11"],["3", "John Doe", "12"]];
    const data = arrayOfArraysToArrayOfObjects(csvFields, csvRows);
    console.log(data);
        2
  •  1
  •   CertainPerformance    6 年前

    一个可能的改进是迭代 数组 csvRows 较小的 阵列( )一次。另外,你可以用 for 相反,与数组方法相比,循环的开销稍小(但可读性较差),因此对于大型文件,循环的性能可能更高:

    const arrayOfArraysToArrayOfObjects = (csvFields, csvRows) => {
      const rowLen = csvRows.length;
      const fieldLen = csvFields.length;
      const results = [];
      for (let i = 0; i < rowLen; i++) {
        const row = csvRows[i];
        const obj = {};
        for (let j = 0; j < fieldLen; j++) {
          obj[csvFields[j]] = row[j];
        }
        results.push(obj);
      }
      return results;
    };
    
    const csvFields = ["id", "name", "age"];
    const csvRows = [
      ["1", "john", "10"],
      ["2", "Jane", "11"],
      ["3", "John Doe", "12"]
    ];
    const data = arrayOfArraysToArrayOfObjects(csvFields, csvRows);
    console.log(data);
        3
  •  1
  •   Nina Scholz    6 年前

    Object.assign 分散单个键/值对象。

    const
        arrayOfArraysToArrayOfObjects = (csvFields, csvRows) => 
            csvRows.map(row => Object.assign(...csvFields.map((k, i) => ({ [k]: row[i] })))),
        csvFields = ["id", "name", "age"],
        csvRows = [["1", "john", "10"], ["2", "Jane", "11"], ["3", "John Doe", "12"]],
        data = arrayOfArraysToArrayOfObjects(csvFields, csvRows);
    
    console.log(data);
    .as-console-wrapper { max-height: 100% !important; top: 0; }