4

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.

7
  • I'm failing at seeing a patron on the modifications? You could remove the obsolete objects and new ones or modify them, one by one. Commented Oct 8, 2015 at 1:22
  • Why object4 and not object4_1? Commented Oct 8, 2015 at 1:22
  • How can you be sure that the duplicates will always have a certain order (if that matters)? Commented Oct 8, 2015 at 1:23
  • It is too difficult to explain why I need this. There are other factors --too complicated to go into. Commented Oct 8, 2015 at 1:23
  • @TimBiegeleisen The order doesn't matter. Thanks for the fast response. Commented Oct 8, 2015 at 1:24

2 Answers 2

3

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.

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

4 Comments

Be careful with the variable set, some environments treat that as a keyword because of Object descriptors for getting and setting.
This is really close, you just don't want to add the _1 to elements that don't repeat.
Yep, pretty close. jsfiddle.net/ansible/sgbkyrc4 I am going to play with this and see if I get it to work -per @SpencerWieczorek's comment.
The latest edit did it. I updated the jsfiddle.net/ansible/sgbkyrc4 Thanks!
0

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.

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.