Reputation: 1220
given the following array of objects:
p =[
{
"object1": "value",
},
{
"object2": "value",
},
{
"object1": "value",
},
{
"object3": "value",
},
{
"object4": "value",
},
{
"object1": "value",
},
{
"object3": "value",
}
];
How would I modify the keys objects with the same key?
So that I have a new array like such:
p =[
{
"object1_1": "value",
},
{
"object2": "value",
},
{
"object1_2": "value",
},
{
"object3_1": "value",
},
{
"object4": "value",
},
{
"object1_3": "value",
},
{
"object3_2": "value",
}
];
I need to keep the structure of the array nearly identical --with just updates to the duplicate keys.
Upvotes: 4
Views: 187
Reputation: 8153
You will have to iterate through the array twice, once to check which keys are repeated, and a second time to replace the values.
var p = [{
"object1": "value",
}, {
"object2": "value",
}, {
"object1": "value",
}, {
"object3": "value",
}, {
"object4": "value",
}, {
"object1": "value",
}, {
"object3": "value",
}];
var timesByKeys = {};
var numberByKeys = {};
function workOnEachKey(fn) {
for (var i = 0; i < p.length; i++) {
var o = p[i];
var key = Object.keys(o)[0];
var timesForKey = timesByKeys[key];
fn(o, key, timesForKey);
}
}
workOnEachKey(function(o, key, timesForKey) {
timesByKeys[key] = timesForKey ? timesForKey + 1 : 1;
numberByKeys[key] = 0;
});
workOnEachKey(function(o, key, timesForKey) {
if (timesForKey !== 1) {
var n = numberByKeys[key] + 1;
numberByKeys[key] = n;
o[key + "_" + n] = o[key];
delete o[key];
}
});
console.log(p);
Run the code snippet and check the console to see the result.
Upvotes: 0
Reputation: 21421
You could count the number of times each key value appears by creating a new object to track the existence of each key.
var set = {};
var changedArray = existingArray.map(function(d){
// since each object has one key
var key = Object.keys(d)[0];
// if the key doesn't exist, add it. if it does, increment it
set[key] = (set[key] || 0) + 1
// create the name
var name = key + '_' + set[key];
// create a new object with the given key
var obj = {};
obj[name] = d[key];
return obj
});
EDIT:
Of course some good points raised below, don't use the name set. also you could avoid the '_1' for the first element by adding an if statement like so
var name;
if (set[key] === 1 ) {
name = key;
} else {
name = key + '_' + set[key];
}
As far as having a '_1' only on elements that repeat - you could always loop through again using the final counts.
Upvotes: 3