通过匹配相同的键值来合并数组中的对象
问题描述:
对不起,如果json不是完美的,我试图将它输入到Stackoverflow窗口中......无论如何,你可以从下面看到我想把所有单独的对象在数组中并将它们合并到具有匹配url的第一个数组中。一旦它们合并,其他所有其他需要从阵列中删除。通过匹配相同的键值来合并数组中的对象
var myArray = [
{
id: '123',
url: 'http://foo.com/1.jpg',
size: 7,
qty: 1
},
{
id: '345',
url: 'http://foo.com/5.jpg',
color: 'blue',
qty: 5
},
{
id: '678',
url: 'http://foo.com/1.jpg',
size: 8,
qty: 4
}];
我需要让这个数组变成... 下面你可以看到,现在已经匹配URL的对象已经移到第一个匹配对象的变化'的关键。之后他们不再分开。它们基本上都匹配在一起并合并到同一个对象中。
var myArray = [{
id: '123',
url: 'http://foo.com/1.jpg',
variations:[
{
id : '123'
size : 7,
qty: 1
},
{
id : '678'
size : 8,
qty: 4
}],
{
id: '345',
url: 'http://foo.com/5.jpg',
color: 'blue',
qty: 5
}];
到目前为止,我有这样的事情:但这只是工作正在进行中。遇到麻烦带到终点线。
myArray.forEach(function(product, index){
var sizeVariations = [];
var currentSearch = product.url;
var filteredArray = processedProducts.filter(function(obj) {
return obj.primary_image === currentSearch;
});
if(filteredArray){
filteredArray.forEach(function(data, index){
sizeVariations.push({
id : data.id,
size : data.size,
quantity : data.qty
});
});
}
});
答
你可以做一些类似的;因为它看起来像数据的重复,所以我没有将ID保持在顶层。
var myArray = [
{
id: '123',
url: 'http://foo.com/1.jpg',
size: 7,
qty: 1
},
{
id: '345',
url: 'http://foo.com/5.jpg',
color: 'blue',
qty: 5
},
{
id: '678',
url: 'http://foo.com/1.jpg',
size: 8,
qty: 4
}];
function mergeObjects(arr)
{
var resultArray = [];
var urls = [];
for(var item in arr)
{
var itemIndex = urls.indexOf(arr[item].url);
if(itemIndex == -1)
{
urls.push(arr[item].url);
var obj = {};
obj.url = arr[item].url;
obj.variations = [];
var variationData = {};
variationData.id = arr[item].id;
if(arr[item].size !== undefined)
{
variationData.size = arr[item].size;
}
if(arr[item].qty !== undefined)
{
variationData.qty = arr[item].qty;
}
if(arr[item].color !== undefined)
{
variationData.color = arr[item].color;
}
obj.variations.push(variationData);
resultArray.push(obj);
}
else
{
var variationData = {};
variationData.id = arr[item].id;
if(arr[item].size !== undefined)
{
variationData.size = arr[item].size;
}
if(arr[item].qty !== undefined)
{
variationData.qty = arr[item].qty;
}
if(arr[item].color !== undefined)
{
variationData.color = arr[item].color;
}
resultArray[itemIndex].variations.push(variationData)
}
}
return resultArray;
}
console.log(mergeObjects(myArray));
答
我想你可以尝试收集所有URL对象中的第一个,这样就可以保证唯一性,然后将其转换为一个数组,这样的事情,
function Merge(arr) {
var obj = {};
for (var elem of arr) {
if (obj[elem.url] == undefined) {
obj[elem.url] = {
id: elem.id,
variations: [],
url: elem.url
};
}
obj[elem.url].variations.push(elem);
delete elem.url;
}
var ans = [];
for (var elem in obj) {
var tmp = {
id: obj[elem].id,
url: elem
};
if(obj[elem].variations.length > 1)
tmp.variations = obj[elem].variations;
else {
tmp.color = obj[elem].variations[0].color;
tmp.qty = obj[elem].variations[0].qty;
}
ans.push(tmp);
}
return ans;
}
答
我觉得自己像一个更好的数据结构将被url
锁定。
const myArray = [{"id":"123","url":"http://foo.com/1.jpg","size":7,"qty":1},{"id":"345","url":"http://foo.com/5.jpg","color":"blue","qty":5},{"id":"678","url":"http://foo.com/1.jpg","size":8,"qty":4}]
const urlMap = myArray.reduce((byUrl, entry) => {
const entryWithoutUrl = Object.assign({}, entry)
delete entryWithoutUrl.url
if (Array.isArray(byUrl[entry.url])) {
byUrl[entry.url].push(entryWithoutUrl)
} else {
byUrl[entry.url] = [entryWithoutUrl]
}
return byUrl
}, Object.create(null))
const newArray = Object.keys(urlMap).map(url => ({
url: url,
variations: urlMap[url]
}))
console.info(newArray)
答
在这个例子中,我已经下破的问题分为两个小问题,因没有通过数组迭代来检查网址已经存在,那么一旦一切都按分组的效率我们将结果对象转换回数组,每个键作为数组中的一个项目。
,如果你使用的函数式编程,你可以组合这些功能结合在一起
compose(objectToArray, sortByUnique)('url', myArray)
var myArray = [
{ id: '123', url: 'http://foo.com/1.jpg', qty: 1, size: 7 },
{ id: '345', url: 'http://foo.com/5.jpg', qty: 5, color: 'blue' },
{ id: '678', url: 'http://foo.com/1.jpg', qty: 4, size: 8 },
{ id: '69', url: 'http://foo.com/1.jpg', qty: 4, size: 8 }
]
function sortByUnique(unique, array) {
// group array by unique key into an object
return array.reduce((acc, x) => {
let key = x[unique]
delete x[unique]
if (acc[key]) {
if (!acc[key].variations) {
let old = acc[key]
acc[key] = {
variations: [old, x]
}
}
else {
acc[key].variations.push(x)
}
}
else {
acc[key] = x
}
return acc
}, {})
}
function objectToArray(obj) {
return Object.keys(obj).map(
k => Object.assign(
{ url: k },
obj[k]
))
}
console.log(
objectToArray(sortByUnique('url', myArray))
)
你尝试过什么?你有什么需要帮助的?请参阅[*如何创建最小,完整和可验证的示例*](http://stackoverflow.com/help/mcve)。 – RobG
我真的不会建议创建这样一个零碎的数据结构(即一些条目与'变体'和一些没有)。另外,你如何确定'id'是否存在于合并条目的变体之外? – Phil
基本上,如果他们有匹配的url值,那么我需要所有的信息都在同一个对象中 – jremi