对JSON格式的对象数组进行迭代,并对其进行修改和扩展,最好使用Undercore.js

Iterate over JSON formatted array of objects and modify and extend it, preferably using Underscore.js

本文关键字:扩展 js Undercore 格式 JSON 对象 数组 迭代 修改      更新时间:2023-09-26

我从一个JSON格式的数据库中检索到数据,该数据被分配给一个变量"var tabs"。

格式化的JSON如下:

[{
    "TAB_ID": "1",
    "TAB_NAME": "TAB ONE",
    "TAB_DISPLAY": "1",
    "QUESTIONS": [{
        "QUESTION_ID": 1,
        "QUESTION": "Question number one",
        "ANSWER": ""
    }, {
        "QUESTION_ID": 2,
        "QUESTION": "Question number two",
        "ANSWER": ""
    }, {
        "QUESTION_ID": 3,
        "QUESTION": "Question number six",
        "ANSWER": ""
    }]
}, {
    "TAB_ID": "1",
    "TAB_NAME": "TAB ONE",
    "TAB_DISPLAY": "1",
    "QUESTIONS": [{
        "QUESTION_ID": 1,
        "QUESTION": "Question number one",
        "ANSWER": "Some Other Answer"
    }, {
        "QUESTION_ID": 2,
        "QUESTION": "Question number two",
        "ANSWER": ""
    }, {
        "QUESTION_ID": 3,
        "QUESTION": "Question number six",
        "ANSWER": "Some Still Different Answer"
    }]
}]

我需要迭代数组并执行以下操作:

对于选项卡中的每个QUESTION,如果QUESTION有一个答案,我需要在QUESTION中添加一个额外的键/值"has_ANSWER":"1"。

    {
        "QUESTION_ID": 1,
        "QUESTION": "Question number one",
        "ANSWER": "Some Other Answer",
        "HAS_ANSWER": "1"
    }

我花了几个小时阅读文章、查看示例代码和阅读Undercore文档,我知道这应该相当简单,但我无法理解如何处理。

我的理解是,我可能想使用嵌套的_.map函数,但我看过的所有示例都返回了对象数组的子集,而不是修改和扩展的子集,并且我需要最终得到完全相同的格式化JSON数据(对象数组),但要有上面提到的更改和添加。

如有任何帮助,我们将不胜感激。

更新:

使用此:

data = _.map(data, obj => _.map(obj.QUESTIONS, q => {
    if (q.ANSWER) {
        q.HAS_ANSWER = 1;
    }
    return q;
}));

这会迭代问题,并相应地修改它们,但返回的对象会删除外层数据——它只返回一个问题数组,而不会保留TAB数据:

    "TAB_ID": "1",
    "TAB_NAME": "TAB ONE",
    "TAB_DISPLAY": "1",

解决方案是对外部数组使用_.each,对内部数组使用_.map。

data = _.each(data, obj => _.map(obj.QUESTIONS, q => {
    if (q.ANSWER) {
        q.HAS_ANSWER = 1;
    }
    return q;
}));

注意:此=>语法仅适用于较新的Javascript实现,目前Safari/Webkit不支持此语法,因此请改用此语法以获得更好的兼容性

data = _.each(data, function(obj){
    _.map(obj.QUESTIONS, function(q){
       if (q.ANSWER) {
           q.HAS_ANSWER = 1;
       }
       return q;
    });
});

这正是我需要的方式。

这可以使用普通的JavaScript,使用Array#map来完成。

// Iterate over data
data = data.map(obj => obj.QUESTIONS.map(q => {
    // If question has answer, then add `HAS_ANSWER` property
    if (q.ANSWER) {
        q.HAS_ANSWER = 1;
    }
    // Update question object
    return q;
}));

var data = [{
    "TAB_ID": "1",
    "TAB_NAME": "TAB ONE",
    "TAB_DISPLAY": "1",
    "QUESTIONS": [{
        "QUESTION_ID": 1,
        "QUESTION": "Question number one",
        "ANSWER": ""
    }, {
        "QUESTION_ID": 2,
        "QUESTION": "Question number two",
        "ANSWER": ""
    }, {
        "QUESTION_ID": 3,
        "QUESTION": "Question number six",
        "ANSWER": ""
    }]
}, {
    "TAB_ID": "1",
    "TAB_NAME": "TAB ONE",
    "TAB_DISPLAY": "1",
    "QUESTIONS": [{
        "QUESTION_ID": 1,
        "QUESTION": "Question number one",
        "ANSWER": "Some Other Answer"
    }, {
        "QUESTION_ID": 2,
        "QUESTION": "Question number two",
        "ANSWER": ""
    }, {
        "QUESTION_ID": 3,
        "QUESTION": "Question number six",
        "ANSWER": "Some Still Different Answer"
    }]
}];
data = data.map(obj => obj.QUESTIONS.map(q => {
    if (q.ANSWER) {
        q.HAS_ANSWER = 1;
    }
    return q;
}));
console.log(data);
document.getElementById('output').innerHTML = JSON.stringify(data, 0, 4);
<pre id="output"></pre>


Undercore/Lodash 中的相同代码

data = _.map(data, obj => _.map(obj.QUESTIONS, q => {
    if (q.ANSWER) {
        q.HAS_ANSWER = 1;
    }
    return q;
}));

使用标准Javascript的Array.prototype.forEach()方法,它可以看起来像这样:

tabs.forEach(tab => {
  tab['QUESTIONS'].forEach(question => {
    if (question['ANSWER']) {
      question['HAS_ANSWER'] = 1;
    }
  });
});

var tabs = [{
    "TAB_ID": "1",
    "TAB_NAME": "TAB ONE",
    "TAB_DISPLAY": "1",
    "QUESTIONS": [{
        "QUESTION_ID": 1,
        "QUESTION": "Question number one",
        "ANSWER": ""
    }, {
        "QUESTION_ID": 2,
        "QUESTION": "Question number two",
        "ANSWER": ""
    }, {
        "QUESTION_ID": 3,
        "QUESTION": "Question number six",
        "ANSWER": ""
    }]
}, {
    "TAB_ID": "1",
    "TAB_NAME": "TAB ONE",
    "TAB_DISPLAY": "1",
    "QUESTIONS": [{
        "QUESTION_ID": 1,
        "QUESTION": "Question number one",
        "ANSWER": "Some Other Answer"
    }, {
        "QUESTION_ID": 2,
        "QUESTION": "Question number two",
        "ANSWER": ""
    }, {
        "QUESTION_ID": 3,
        "QUESTION": "Question number six",
        "ANSWER": "Some Still Different Answer"
    }]
}];
tabs.forEach(tab => {
  tab['QUESTIONS'].forEach(question => {
    if (question['ANSWER']) {
      question['HAS_ANSWER'] = 1;
    }
  });
});
console.log(tabs);

这种方法会修改现有的数据。