1

So I have these items and it has some duplicated ID's but the values are different. It might be more items but currently I used these items for example. The array result is like this:

"items": [
    {
        "id": "E46",
        "size": "5 Ounce"
    },
    {
        "id": "E46",
        "color": "Green"
    },
    {
        "id": "E32",
        "size": "8 Ounce"
    },
    {
        "id": "E32",
        "color": "Green"
    },
    {
        "id": "E4G",
        "size": "5 Ounce"
    },
    {
        "id": "E4G",
        "color": "Pink"
    },
    {
        "id": "E3C",
        "size": "8 Ounce"
    },
    {
        "id": "E3C",
        "color": "Pink"
    }
]

I'd like combine these and make it look like this:

"items": [
    {
        "id": "E46",
        "size": "5 Ounce"
        "color": "Green"
    },
    {
        "id": "E32",
        "size": "8 Ounce"
        "color": "Green"
    },
    {
        "id": "E4G",
        "size": "5 Ounce"
        "color": "Pink"
    },
    {
        "id": "E3C",
        "size": "8 Ounce"
        "color": "Pink"
    }
]

If it's possible, Thanks:

1
  • @bdkopen It has JavaScript tagged, but JSON in the title. Just guessing here, it's JSON that's created in JavaScript. Maybe partial code, maybe OP is just bad at JSON/JS. Who knows? Commented May 9, 2017 at 1:53

4 Answers 4

4

You could do something like this:

var data = { items: 
[{ id: 'E46', size: '5 Ounce' },
 { id: 'E46', color: 'Green' },
 { id: 'E32', size: '8 Ounce' },
 { id: 'E32', color: 'Green' },
 { id: 'E4G', size: '5 Ounce' },
 { id: 'E4G', color: 'Pink' },
 { id: 'E3C', size: '8 Ounce' },
 { id: 'E3C', color: 'Pink' } ] }

var result = {}

data.items.forEach(function (item) { //1
    Object.keys(item).forEach(function(key) { //2
        if (!result[item.id]) result[item.id] = {}; //3
        result[item.id][key] = item[key]; //4
    });
})

Here is what is happening:

//1 We loop through each item in the items array

//2 We loop through each key in individual item from the items array

//3 We create a key-value pairing using the item id and an empty object

//4 We add the current key-value pair our new item object made inside our result object.

The result object would then have this value:

{ E46: { id: 'E46', size: '5 Ounce', color: 'Green' },
  E32: { id: 'E32', size: '8 Ounce', color: 'Green' },
  E4G: { id: 'E4G', size: '5 Ounce', color: 'Pink' },
  E3C: { id: 'E3C', size: '8 Ounce', color: 'Pink' } }

If you wanted to put this back into an array, all you would have to do is loop through each key-value pair in the object and add all of the values to an array, like so:

var arrayResult = []
Object.keys(result).forEach(function(key) {
    arrayResult.push(result[key])
});

And then your arrayResult variable would have this value:

[ { id: 'E46', size: '5 Ounce', color: 'Green' },
  { id: 'E32', size: '8 Ounce', color: 'Green' },
  { id: 'E4G', size: '5 Ounce', color: 'Pink' },
  { id: 'E3C', size: '8 Ounce', color: 'Pink' } ]

which you could use anywhere else in your program.

Sign up to request clarification or add additional context in comments.

Comments

1
function mergeObjectWithSameId(items) {
  let output = []
  items.forEach((item) => {
    if (output.filter(existingItem => existingItem.id === item.id).length === 0) {
      output.push(item)
    } 
    else {
      const existingItem = output.filter(existingItem => existingItem.id === item.id)[0]
      Object.keys(item).forEach(key => {
        if(!existingItem[key]) {
          existingItem[key] = item[key]
        }
      })
    }
  })
  return output
}

I have tested it in the Chrome console.

Just run mergeObjectWithSameId(items) and Voila you get your expecting result!

Comments

0

Assuming that you've looking for a JavaScript solution, and that you've already parsed the 'items' JSON in the question into a JavaScript Object (itemsParsed below), you can achieve the restructuring of your data in two steps.

The first is to create a hashmap of the data where the repeated 'id' property represents the keys in a new Object, like so...

var itemsParsed = theParsedJSON;

var itemHolder = (function() {
    var O = {}, ID;
    itemsParsed.forEach(function(o) {
        Object.keys(o).forEach(function(a) {
            if (a === 'id') {
                ID = o.id;
                if (!O[ID]) O[ID] = {};
            } else {
                O[ID][a] = o[a];
            }
        });
    });
    return O;
}());

This will return the Object itemHolder as so...

itemHolder = {
    E46: { 
        size: "5 Ounce" 
        color: "Green" 
    } 
    E32: { 
        size: "8 Ounce" 
        color: "Green" 
    } 
    E4G: { 
        size: "5 Ounce" 
        color: "Pink" 
    } 
    E3C: { 
        size: "8 Ounce" 
        color: "Pink" 
    }
};

The next step is to use this structure in another another step transformation from which fresh Objects can be created and pushed into new a array, like so...

var newItems = [];

Object.keys(itemHolder).forEach(function(n) {
    var tmp = itemHolder[n];
    var newObj = {
        id: n
    };
    Object.keys(tmp).forEach(function(x) {
        newObj[x] = tmp[x];
    });
    newItems.push(newObj);
});

The structure of the newItems array can be seen when the JSON.stringify method is applied to it...

console.log(JSON.stringify(newItems, null, 4));
/* ==>
[
    {
        "id": "E46",
        "size": "5 Ounce",
        "color": "Green"
    },
    {
        "id": "E32",
        "size": "8 Ounce",
        "color": "Green"
    },
    {
        "id": "E4G",
        "size": "5 Ounce",
        "color": "Pink"
    },
    {
        "id": "E3C",
        "size": "8 Ounce",
        "color": "Pink"
    }
]
*/

Hope that helps. :)

Comments

0

You could reduce the array. Create an accumulator object with each unique id as key and merge each object using Object.assign() based on the id

const items=[{id:"E46",size:"5 Ounce"},{id:"E46",color:"Green"},{id:"E32",size:"8 Ounce"},{id:"E32",color:"Green"},{id:"E4G",size:"5 Ounce"},{id:"E4G",color:"Pink"},{id:"E3C",size:"8 Ounce"},{id:"E3C",color:"Pink"}];

const merged = items.reduce((acc, o) => {
  acc[o.id] = Object.assign(acc[o.id] || {}, o)
  return acc;
}, {})

const output = Object.values(merged)

console.log(output)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.