【问题标题】:Issue while converting array from one format to another将数组从一种格式转换为另一种格式时出现问题
【发布时间】:2018-08-24 06:30:36
【问题描述】:

我有以下输入数组(这是一个 Javascript Object[] 数组响应):

[
    {index:1, headerCSV:"Name", dataFields: ["Name", "Id"]},
    {index:2, headerCSV:"Id", dataFields: ["Test", "Test 1"]},
    {index:3, headerCSV:"fname", dataFields: ["Test", "Test 1"]},
    {index:4, headerCSV:"lname", dataFields: []},
]

我正在尝试将其转换为以下数组:

[
    {"header" : 1, "field" :"Name"},
    {"header" : 1, "field" :"Id"},
    {"header" : 2, "field" :"Test"},
    {"header" : 2, "field" :"Test 1"},
    {"header" : 3, "field" :"Test"},
    {"header" : 3, "field" :"Test 1"}
]

在结果数组中,我需要将header 与输入数组index 一起放入field,我需要使用输入数组的dataFields 数组进行构造.我已尝试使用以下代码:

var CSVHeadersAndFields = /* The input array */;
var headerFieldMappingJSON = [];
for(var i=0; i<CSVHeadersAndFields.length;i++) {
    headerFieldMappingJSON[i] = {};
    var selectedFields = CSVHeadersAndFields[i].dataFields;
    for(var j=0; j<selectedFields.length;j++) {
        headerFieldMappingJSON[i].header = CSVHeadersAndFields[i].index;
        headerFieldMappingJSON[i].field = selectedFields[j];
    }
}

但是我得到了以下结果:

[
    {"header":1,"field":"Name"},
    {"header":2,"field":"Test"},
    {"header":3,"field":"Test"},
    {}
]

我怀疑 for 循环的第一次迭代值被第二次迭代替换,而且我需要避免从输入数组中的 dataFields 的空数组构造输出数组映射。

如何做出正确的算法来转换数组?

【问题讨论】:

  • 您能否以 JSON/对象文字格式而不是 dataFields:Array(2) 等格式发布实际的数组响应,以便重现您的情况?
  • 0:{index: 0, headerCSV: "Id", dataImportFields: Array(2), dataImportFieldsStr: "Id,Name", isMap: false} 1:{index: 1, headerCSV: "名称”,dataImportFields:Array(0),dataImportFieldsStr:“”,isMap:true} 2:{index:2,headerCSV:“FirstName”,dataImportFields:Array(2),dataImportFieldsStr:“Id,Name”,isMap:false } 3:{index: 3, headerCSV: "LastName", dataImportFields: Array(0), dataImportFieldsStr: "", isMap: true}
  • 你到处都有Array(2)s...
  • 如果您可以显示您期望fields 的输出是其中一行的内容,那将有所帮助。
  • 问题中已经有实际响应,问题中也有 dataFields.Array[2]。

标签: javascript arrays algorithm


【解决方案1】:

为结果数组创建一个单独的迭代器索引。或者只是推送到结果数组而不是按索引添加值:

var CSVHeadersAndFields = /* The array from question */;
var headerFieldMappingJSON = [];
for(var i = 0; i < CSVHeadersAndFields.length; i++) {
    var selectedFields = CSVHeadersAndFields[i].dataFields;
    for(var j = 0; j < selectedFields.length; j++) {
        headerFieldMappingJSON.push({
            header: CSVHeadersAndFields[i].index,
            field: selectedFields[j]
        });
    }
}

同样的例子,但更简洁:

var input = /* The array from question */;
var output = [];

input.forEach(function (csvRow) {
    csvRow.dataFields.forEach(function (field) {
        output.push({
            header: csvRow.index,
            field: field
        });
    });
});

【讨论】:

    【解决方案2】:

    您可以尝试以下方法:

    逻辑:

    • 循环数据并将数据推送到基于解析逻辑的数组中。
    • 在每次迭代中,您可以再次循环 obj.dataFields 并为每个字段创建对象。
    • 然后您可以将此输出数组合并到原始输出列表。

    var data = [
      {index:1, headerCSV:"Name", dataFields: ["Name", "Id"] },
      {index:2, headerCSV:"Id", dataFields: ["Test", "Test 1"] },
      {index:3, headerCSV:"fname", dataFields: ["Test", "Test 1"] },
      {index:4, headerCSV:"lname", dataFields: []}
    ];
    
    var output = data.reduce((acc, obj) => {
      const header = obj.index;
      return acc.concat( obj.dataFields.map((field) => ({ header, field}) ))
    }, []);
    
    console.log(output)

    【讨论】:

      【解决方案3】:

      下面的代码将为每个dataField 提供一个结果对象,并将CSVHeadersAndFields 中的index 属性用作每个header 属性。

      const result = CSVHeadersAndFields.map(item => item.dataFields.map(field => { return { header: item.index, field } }) );

      【讨论】:

      • 我不认为它符合作者的要求。他需要将响应值转换为 header-field 值。
      • 哦,等等,我明白了!
      【解决方案4】:

      这里是更简单的代码:

          var CSVHeadersAndFields = [ {index:1, headerCSV:"Name", dataFields: ["Name","Id"]},
           {index:2, headerCSV:"Id", dataFields:["Test","Test 1"]},{index:3, headerCSV:"fname", dataFields:["Test","Test 1"]}, {index:4, headerCSV:"lname", dataFields:[]};
      
          var headerFieldMappingJSON  = [];
      
         for(var CSVHeadersAndField of CSVHeadersAndFields ) {
             for(var dataFieldVal of CSVHeadersAndField['dataFields']){
               headerFieldMappingJSON.push({'header': CSVHeadersAndField['index'], 'field': dataFieldVal })
             }
         }
      

      输出:

      [
        {
          "header": 1,
          "field": "Name"
        },
        {
          "header": 1,
          "field": "Id"
        },
        {
          "header": 2,
          "field": "Test"
        },
        {
          "header": 2,
          "field": "Test 1"
        },
        {
          "header": 3,
          "field": "Test"
        },
        {
          "header": 3,
          "field": "Test 1"
        }
      ]
      

      【讨论】:

      • 我得到以下异常,未捕获的操作失败:Header_Field_Mapping$controller$handleNext [CSVHeadersAndField.dataFields is not iterable]
      • 我在我的机器上运行并在这里粘贴代码,没有异常也没有错误,您使用的是哪种语言?
      • 无论如何,该错误是因为您可能更改了“dataFields”类型,它应该是一个要迭代的数组,在您发布的这个示例中就是这种情况。
      • 我没有更改数据类型,它仍然是数组。
      猜你喜欢
      • 2016-10-09
      • 2011-03-17
      • 2018-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多