在JSON中将一个对象推送到另一个对象

时间:2017-12-23 13:47:14

标签: javascript json

所以例如我有这样的对象:

{
  data: [
    {
      id: 13,
      name: "id13"
    },
    {
      id: 21,
      name: "id21"
    }
  ],
  included: [
    {
      id: "13",
      badge: true
    },
    {
      id: "21",
      badge: false
    }
  ]
}

现在我需要循环包含并推送包含在id等于的数据中。

因此,在转换之后,数据中会有徽章,例如:

{
  data: [
    {
      id: "13",
      name: "id13",
      included: {
        id: "13",
        badge: true
      },
    },
    {
      id: "21",
      name: "id21",
      included: {
        id: "21",
        badge: false
      }
    }   
  ]
}

当然我自己尝试了,我已经创建了这段代码:

for(let i=0; i<includedLength; i++) {
  console.log(a.included[i].id);
  for(n=0; n<dataLength; n++) {
    console.log(a.data[n]);
    if(a.icluded[i].id === a.data[i].id) {
      console.log('We have match!!!');
    }
  }
}

但它不起作用我在控制台中有错误

  

未捕获的TypeError:无法读取未定义的属性“0”

这是我的代码的demo

5 个答案:

答案 0 :(得分:4)

这里的所有解决方案都和你一样走了,效率不高。所以我发布了我的解决方案,它比目前为止的其他解决方案更有效。阅读代码注释以了解所完成的优化。

// Convert data array into a map (This is a O(n) operation)
// This will give O(1) performance when adding items.
let dataMap = a.data.reduce((map, item) => {
    map[item.id] = item;
    return map;
}, {});

// Now we map items from included array into the dataMap object
// This operation is O(n). In other solutions, this step is O(n^2)
a.included.forEach(item => {
    dataMap[item.id].included = item;
});

// Now we map through the original data array (to maintain the original order)
// This is also O(n)
let finalResult = {
    data: a.data.map(({id}) => {
        return dataMap[id];
    })
};

console.log(JSON.stringify(finalResult))

答案 1 :(得分:1)

这是我的解决方案,这将提供所需的输出!

它为循环保留了相同的标准。

我想强调的一点是,

  1. id属性中的included是字符串,因此您可以使用+运算符将其转换为数字。

  2. 使用Object.assign()方法,以便我们创建相应对象的新副本。阅读更多here

  3. &#13;
    &#13;
    var data = {
      data: [{
          id: 13,
          name: "id13"
        },
        {
          id: 21,
          name: "id21"
        }
      ],
      included: [{
          id: "13",
          badge: true
        },
        {
          id: "21",
          badge: false
        }
      ]
    }
    
    var output = {
      data: data.data
    };
    
    for (var q of data.included) {
      for (var j of output.data) {
        if (+q.id === j.id) {
          j['included'] = Object.assign({}, j);;
        }
      }
    }
    console.log(output);
    &#13;
    .as-console {
      height: 100%;
    }
    
    .as-console-wrapper {
      max-height: 100% !important;
      top: 0;
    }
    &#13;
    &#13;
    &#13;

答案 2 :(得分:1)

它不是JSON,它是一个对象。有效的json包含其键和值作为字符串。你要做的是操纵一个对象。以下代码应有助于获得所需的输出。

const obj ={
  data: [
    {
      id: 13,
      name: "id13"
    },
    {
      id: 21,
      name: "id21"
    }
  ],
  included: [
    {
      id: "13",
      badge: true
    },
    {
      id: "21",
      badge: false
    }
  ]
}

for (var i=0; i<obj.data.length;i++){
  for(var j=0; j< obj.included.length;j++){
  if(obj.data[i].id == obj.included[j].id){
  	obj.data[i].included={
    id: obj.included[j].id,
    badge: obj.included[j].badge
    }
  }
  }
}

delete obj.included

console.log(obj)

我在做她的是:

  1. 检查obj.data的id是否等于obj.included的内容

  2. 如果相等,请在obj [data]中添加一个名为“included”的新密钥

  3. 当循环结束时,不再需要从obj中删除“included”键。

答案 3 :(得分:1)

当找到匹配时,将整个“included”元素推入第一个数组似乎是浪费空间(你真的需要那个额外的id元素吗?) - 所以这只是输出像

[{id: 1, name: 'name', badge: true},{...}]

如果未找到匹配的徽章元素,则会将徽章设置为false。

var notJSON = {
  data: [
    {
      id: 13,
      name: "id13"
    },
    {
      id: 21,
      name: "id21"
    }
  ],
  included: [
    {
      id: "13",
      badge: true
    },
    {
      id: "21",
      badge: false
    }
  ]
};

var badged = notJSON.data.map(function (el, i) {
  el.badge = notJSON.included.find(function (inc) {
    return inc.id == el.id;
  }).badge || false;
  return el;
});

console.log(badged);

答案 4 :(得分:1)

var obj = {
  data: [
    {
      id: 13,
      name: "id13"
    },
    {
      id: 21,
      name: "id21"
    }
  ],
  included: [
    {
      id: "13",
      badge: true
    },
    {
      id: "21",
      badge: false
    }
  ]
};

obj.included.forEach((item) => {
    obj.data.forEach(item1 => {
    if(item.id == item1.id){
        item1.included = item;
    }
  });
});
delete obj.included;