如何以有效的方式将混合值的arrary转换为JSON数组?

时间:2016-02-11 13:00:31

标签: javascript arrays json serialization asp.net-web-api

在我的场景中,我有序列化的HTML数组:

[{ name: "Questions[0].ID", value: 1 }, {name: "Questions[0].Answer", value: "Yes"}, { name: "Questions[1].ID", value: 2 }, {name: "Questions[1].Answer", value: "No"}]

我需要序列化此HTML表单并更改其格式,因为此HTML处于部分视图中,用于发布整个表单的其他位置。但在这里,我只对问题数据感兴趣,需要以特定的JSON格式发布。

JSON结构将是:

[{ QuestionID: 1, Answer: "Yes" }, { QuestionID: 2, Answer: "No" }]

解决方案1 ​​ - 循环播放数组:

var surveyResponses = [{
  name: "Questions[0].ID",
  value: 1
}, {
  name: "Questions[0].Answer",
  value: "Yes"
}, {
  name: "Questions[1].ID",
  value: 2
}, {
  name: "Questions[1].Answer",
  value: "No"
}];
var responsesList = new Array();
if (surveyResponses != null && surveyResponses.length > 0) {
  for (var i = 0; i < surveyResponses.length; i++) {
    var answer = surveyResponses[i++].value;
    var questionID = surveyResponses[i].value;
    responsesList.push({
      QuestionID: questionID,
      Answer: answer
    });
  }
}
document.write("<pre>" + JSON.stringify(responsesList) + "</pre>")

解决方案2 - Grep + Map:

var surveyResponses = $("#QuestionsDiv").serializeArray();
var offset = 0;
var responsesList = $.grep(surveyResponses,
    function (answer) {
        return answer.name.indexOf("Answer") > -1;
    }).map(function (answer, i) {
        return { QuestionID: surveyResponses[i + (++offset)].value, Answer: answer.value };
    });

到目前为止,我想出了这两个解决方案。我特别喜欢 Solution 2 ,但代码可读性并不是最好的。

还有其他(更好)的方式进行此转换吗?特别是没有循环遍历数组?

2 个答案:

答案 0 :(得分:3)

您可以使用reduce;

var out = arr.reduce(function(p, c, i, a) {
  if (i === 0 || i % 2 === 0) {
    p.push({ QuestionID: a[i].value, Answer: a[i + 1].value });
  }
  return p;
}, []);

DEMO

然而,这将击中每个数组元素。我不确定你为什么不反对循环,但这是迄今为止最简单的方法,并且只会击中所有其他元素。

for (var out = [], i = 0, l = arr.length; i < l; i+=2) {
  out.push({ QuestionID: arr[i].value, Answer: arr[i + 1].value });
}

DEMO

答案 1 :(得分:2)

您可以尝试这样的事情:

不确定它是否更好,但是另一种方法。

var data = [{ name: "Questions[0].ID", value: 1 }, {name: "Questions[0].Answer", value: "Yes"}, { name: "Questions[1].ID", value: 2 }, {name: "Questions[1].Answer", value: "No"}];

var _tmp = {};
data.forEach(function(item){
  var k = item.name.split(".");
  if(!_tmp[k[0]])
    _tmp[k[0]] = {}
  
    if(k[1]==="ID")
      k[1] = "QuestionID"
  _tmp[k[0]][k[1]] = item.value;
});

var result = Object.keys(_tmp).map(function(k){return _tmp[k]});

document.write("<pre>" + JSON.stringify(result,0,2) + "</pre>")