根据索引从两个单独的数组中创建一个对象

问题描述

我正在尝试采用此数组数组,

const parsedCsvData = [
  [
    "Passage","Percentage of","constraint2","1","2","",""
  ],[
    "","Avg A Param","0.3","0.9"
  ],[
    "Item","Include","constraint1","4","Item Identifier","I105_15201",""
  ]
]

并使用其值填充该对象

const template = {
  "attributeName": "","constraintType": "","objectType": "","filters": [
    {
      "objectType": "","attributeName": "","values": "","valueLowerBound": "","valueUpperBound": ""
    }
  ],"upperBound": "","description": "","lowerBound": ""
}

parsedCsvData中的每个数组都是我解析的CSV文件中的一行。数组数组中的每个值都基于另一个数组进行索引

const csvHeaders = [
  "objectType","constraintType","description","lowerBound","upperBound","attributeName","referenceValue","scope","filters","values","valueLowerBound","valueUpperBound"
]

例如,在parsedCsvData的第一个子数组中, Passage 的索引为0,而csvHeaders中 objectType 的值。同样,说明位于索引2,分别为 constraint1 constraint2

此外,如果csv中索引8处存在 filters 值,则会创建一个新行。解析后,这将为每个过滤器值创建一个新的子数组。但是,每个 filters 值和以下三个 values valueLowerBound valueUpperBound 都属于同一模板对象作为过滤器键下的子数组。

以下是鉴于上面我发布的内容,我尝试完成的输出示例。不用管空键/值对。

[{
  "constraintType": "Percentage of","objectType": "Passage","filters": [
    {
      "attributeName": "Avg A Param","valueLowerBound": "0.3","valueUpperBound": "0.9"
    } // there may be multiple filter objects as part of this array
  ],"upperBound": "2","description": "constraint2","lowerBound": "1"
},{
  "constraintType": "Include","objectType": "Item","filters": [
    {
      "attributeName": "Item Identifier","values": "I105_15201","upperBound": "4","description": "constraint1","lowerBound": "1"
}
]

我尝试映射csvHeaders数组,尝试使用它们的索引,然后对parsedCsvData值进行映射,并将其分配给模板对象,但似乎无法使其正常工作。任何帮助将不胜感激。

解决方法

一种方法,通过检查嵌套arra的第一个元素来分配新对象或分配新的嵌套对象。

    const
        parsedCsvData = [["Passage","Percentage of","constraint2","1","2","",""],["","Avg A Param","0.3","0.9"],["Item","Include","constraint1","4","Item Identifier","I105_15201",""]],template = ["objectType","constraintType","description","lowerBound","upperBound","xxxx","referenceValue","scope","attributeName","values","valueLowerBound","valueUpperBound"],result = parsedCsvData.reduce((r,a) => {
            const
                assign = (object,target,value) => {
                    const
                        keys = target.split('.'),last = keys.pop();

                    keys.reduce((o,k) => o[k] = o[k] || {},object)[last] = value;
                };

            if (a[0]) {
                r.push(a.reduce((t,v,i) => {
                    if (v) assign(t,template[i],v);
                    return t;
                },{}));
            } else {
                r[r.length - 1].filters = r[r.length - 1].filters || [];
                r[r.length - 1].filters.push(a.reduce((t,{}));
            }
            return r;
        },[]);
        
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }