JSON - 如何使用javascript reduce()合并2个数据集

时间:2017-05-31 11:38:43

标签: javascript json

我需要合并两组JSON数据 - 将 productsBrands 产品合并,使用javascript实现此目的的最佳方法是什么?

ProductBrands JSON数据:

const productBrands = {
  "Brand A": {
    "Brand D": {},
    "Brand E": {}
  },
  "Brand B": {
    "Brand F": {},
    "Brand G": {}
  }
};

产品JSON数据:

const products= [
  {
    "Brand A": {
      "BrandName": "Brand A",
      "HasChildBrands": {}
    },
    "Brand B": {
      "BrandName": "Brand B",
      "HasChildBrands": {}
    },
    "Brand C": {
      "BrandName": "Brand C",
    },
    "Brand D": {
      "BrandName": "Brand D",
    },
    "Brand E": {
      "BrandName": "Brand E",
    },
    "Brand F": {
      "BrandName": "Brand F",
    },
    "Brand G": {
      "BrandName": "Brand G",
    }
  }
];

预期的合并输出:

const products= [
  {
    "Brand A": {
      "BrandName": "Brand A",
      "HasChildBrands": {
        "BrandName": "Brand D",
      },
      {
        "BrandName": "Brand E",
      }
    },
    "Brand B": {
      "BrandName": "Brand B",
      "HasChildBrands": {
        "BrandName": "Brand F",
      },
      {
        "BrandName": "Brand G",
      }
    },
    "Brand C": {
      "BrandName": "Brand C",
    },
    "Brand D": {
      "BrandName": "Brand D",
    },
    "Brand E": {
      "BrandName": "Brand E",
    },
    "Brand F": {
      "BrandName": "Brand F",
    },
    "Brand G": {
      "BrandName": "Brand G",
    }
  }
];

以下是我到目前为止所尝试的内容,但它仍然不是我的预期:

let products = data.reduce(function (acc, obj) {
  let item = Object.values(obj)[0]; //Get Indented Objects of Data
  let BrandNames = item.BrandName; //Obtain "Brand A", "Brand B", "Brand C" ... so on.
  let KeysForChildBrands = Object.keys(childBrands);
  if($.inArray(BrandNames, KeysForChildBrands) != -1){ //Check if Brand Name existed in ProductBrands data
    item['HasChildBrands'] = ProductBrands[BrandNames];
  }
  acc.push(obj);
  return acc;
},[]);
console.log(JSON.stringify(products)); //Got stuck here.

2 个答案:

答案 0 :(得分:1)

我认为您应该更改products的格式以简化计算,因为现在products是一个对象数组

我知道这与你的输出没有对齐,因为在结果数组中你重复BrandName个键,这不是正确的语法,下面是你应该维护数据的正确形式(至少逻辑上它)是正确的,但不是很有效)

var productBrands = {
  "Brand A": {
    "Brand D": {},
    "Brand E": {}
  },
  "Brand B": {
    "Brand F": {},
    "Brand G": {}
  }
};

var products= [
    {
      "BrandName": "Brand A",
      "HasChildBrands": {}
    },
    {
      "BrandName": "Brand B",
      "HasChildBrands": {}
    },
    {
      "BrandName": "Brand C",
        "HasChildBrands": {}
    },
    {
      "BrandName": "Brand D",
        "HasChildBrands": {}
    },
    {
      "BrandName": "Brand E",
        "HasChildBrands": {}
    }

];

for(obj in products)
{

    products[obj].HasChildBrands = productBrands[products[obj].BrandName];
}
console.log(products);

答案 1 :(得分:1)

只需将HasChildBrands转换为数组

即可
"Brand A": {
    "BrandName": "Brand A",
    "HasChildBrands": []
},

和数据到对象而不是数组

const data= {
    "Brand A": {
      "BrandName": "Brand A",
      "HasChildBrands": []
    },
    "Brand B": {
      "BrandName": "Brand B",
      "HasChildBrands": []
    },
    "Brand C": {
      "BrandName": "Brand C",
    },
    "Brand D": {
      "BrandName": "Brand D",
    },
    "Brand E": {
      "BrandName": "Brand E",
    },
    "Brand F": {
      "BrandName": "Brand F",
    },
    "Brand G": {
      "BrandName": "Brand G",
    }
  };

使用这段代码合并对象

Object.keys(data).forEach(function(val){
        if(childBrands[val]){
           var childs = Object.keys(childBrands[val]);
           childs.forEach(function(child){
               data[val].HasChildBrands.push({'BrandName':child});
           });

        }
    });

<强>段

const childBrands = {
  "Brand A": {
    "Brand D": {},
    "Brand E": {}
  },
  "Brand B": {
    "Brand F": {},
    "Brand G": {}
  }
};

const data= {
    "Brand A": {
      "BrandName": "Brand A",
      "HasChildBrands": []
    },
    "Brand B": {
      "BrandName": "Brand B",
      "HasChildBrands": []
    },
    "Brand C": {
      "BrandName": "Brand C",
    },
    "Brand D": {
      "BrandName": "Brand D",
    },
    "Brand E": {
      "BrandName": "Brand E",
    },
    "Brand F": {
      "BrandName": "Brand F",
    },
    "Brand G": {
      "BrandName": "Brand G",
    }
  };

Object.keys(data).forEach(function(val){
    if(childBrands[val]){
       var childs = Object.keys(childBrands[val]);
       childs.forEach(function(child){
           data[val].HasChildBrands.push({'BrandName':child});
       });
  
    }
});

console.log(data);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>