如何根据某些条件合并2个对象的嵌套数组属性?

时间:2019-01-25 06:26:03

标签: javascript jquery arrays

我需要比较以下两个数组并更新嵌套数组中的状态

var arr1 = {
   "questionInfo": [{
         "questionId": "300002",
         "quesOptions": [{
            "optionId": "000000",
            "status": 1
         }]
      },
      {
         "questionId": "300003",
         "quesOptions": [{
               "optionId": "300015",
               "status": 1
            },
            {
               "optionId": "300016",
               "status": 1
            }
         ]
      }
   ]
};
var arr2 = {
   "questionInfo": [{
         "questionId": "300002",
         "quesOptions": [{
               "optionId": "000000"
            },
            {
               "optionId": "11111111"
            }
         ]
      },
      {
         "questionId": "300003",
         "quesOptions": [{
            "optionId": "300016"
         }]
      }
   ]
};

我需要将arr1值更改为以下格式,我需要比较两个数组,并且如果其中存在 optionId ,我需要更新 questionOptions 数组状态arr2需要将状态更新为1,否则需要更新为0

    var arr1 = {
        "questionInfo": [
            {
                "questionId": "300002",
                "quesOptions": [
                    {
                        "optionId": "000000",
                        "status": 1
                    },
                    {
                        "optionId":"11111111",
                        "status": 1
                    }
                ]
            },
            {
                "questionId": "300003",
                "quesOptions": [
                    {
                        "optionId": "300015",
                        "status": 0
                    },
                    {
                        "optionId":"300016",
                        "status":1
                    }
                ]
            }
        ]
    };

我尝试了以下方法,但是无法正常工作。

for (var i = 0; i < arr1.length; i++) {
   for (var j = 0; j < arr1[i].quesOptions.length; j++) {
      if (arr1[i].quesOptions[j].optionId !== arr2[i].quesOptions[j].optionId) {
         arr2[i].quesOptions[j].status = 1;
      } else {
         arr2[i].quesOptions[j].status = 0
      }
   }
}

有人可以帮助我解决这个问题吗?

1 个答案:

答案 0 :(得分:2)

您可以使用reduce进行合并两个内部数组的操作:

var arr1={"questionInfo":[{"questionId":"300002","quesOptions":[{"optionId":"000000","status":1}]},{"questionId":"300003","quesOptions":[{"optionId":"300015","status":1},{"optionId":"300016","status":1}]}]},

    arr2={"questionInfo":[{"questionId":"300002","quesOptions":[{"optionId":"000000"},{"optionId":"11111111"}]},{"questionId":"300003","quesOptions":[{"optionId":"300016"}]}]}

arr1.questionInfo.forEach(q1 => {
  const q2 = arr2.questionInfo.find(q => q.questionId === q1.questionId);
  const map1 = q1.quesOptions.reduce((acc,{optionId}) => (acc[optionId] = {optionId, status:0}, acc), {})
  const map2 = q2.quesOptions.reduce((acc,{optionId}) => (acc[optionId] = {optionId, status:1}, acc), {});
    
  q1.quesOptions = Object.values({...map1, ...map2})
})

console.log(arr1)

首先,使用findq1中找到当前arr2.questionInfo的等效值,

然后使用map1创建一个300002对象,看起来像这样(对于reduce

{
  "000000": {
    "optionId": "000000",
    "status": 0
  }
}

如您所见,默认情况下,我们将状态设置为0

q2的Silimary,创建另一个map2对象,该对象的默认status设置为1。对于300002,它看起来是

{
  "11111111": {
    "optionId": "11111111",
    "status": 1
  },
  "000000": {
    "optionId": "000000",
    "status": 1
  }
}

使用扩展语法合并它们时,

  • 如果仅optionId首先存在,将从map1中获取。因此status将是0
  • 如果两个都存在optionId,则map2的值将覆盖map1的对象。因此,您得到的状态设置为1
  • 如果optionId仅存在于第二个对象中,它将从map2取而status设置为1

然后最后使用Object.values()将合并对象的值放入数组中。

更新

如果Object.values()supported in your browser,则扩展语法也为might not be supported。您可以使用Object.assignmap采取另一种方法(应该在map2缩小之后添加):

const merged = Object.assign({}, map1, map2);
q1.quesOptions = Object.keys(merged).map(function(key) {
   return merged[key];
})