There is no "error" if you use more than one key with the same name, but in JSON, the last key with the same name is the one that is going to be used.

In your case, the key "name" would be better to contain an array as it's value, instead of having a number of keys "name". It doesn't make much sense the same object or "thing" to have two names, or two of the same properties that are in conflict.

E.g.:

{
  "name" : [ "JOHN", "JACK", "...", ... ]
}
Answer from JeanK on Stack Overflow
🌐
Google Groups
groups.google.com › g › pegjs › c › w0OR3Bhkz9k
About JSON grammar example - multiple same-name keys
"The JSON grammar is used to translate a String describing a set of ECMAScript objects into actual objects. [...]" So to me it seems that JSON grammar in strict mode should not allow for "multiple data property assignments with the same name".
Top answer
1 of 7
13

You can use reduce() and concat() methods for this.

const data = [{"meine_frage":"hier kommt die antwort","ne_andere_frage":"ne andere antwort","was_willst_du":"alles","mehr_zur_auswahl":["einiges","vieles und","gär nix"]},{"meine_frage":"tom & jerry","ne_andere_frage":"mickey maus","was_willst_du":"oder","mehr_zur_auswahl":["manches","einiges","vieles und","gär nix"]},{"meine_frage":"dick und doof","ne_andere_frage":"minnie muas","was_willst_du":"nichts","mehr_zur_auswahl":["gär nix"]}]

// Use the `reduce` method to accumulate results into a single object.
const result = data.reduce(function(r, e) {
  // Iterate over each key in the current object.
  return Object.keys(e).forEach(function(k) {
    // Check if the key exists in the result object.
    if(!r[k]) r[k] = [].concat(e[k]) // If the key doesn't exist, initialize it as an array containing the value from the current object.       
    else r[k] = r[k].concat(e[k]) // If the key does exist, concatenate the existing array with the value from the current object.
  }), r // Return the updated result object for the next iteration.
}, {}) // Start with an empty object `{}` as the initial value of `result`.

console.log(result)

2 of 7
5

You could use reduce method by passing a callback function as parameter.

The algorithm is follow: if final object already contains one key then you should initialize the key's value with an empty array. Otherwise, you should append to array value from all items from the array.

let data = [{"meine_frage":"hier kommt die antwort","ne_andere_frage":"ne andere antwort","was_willst_du":"alles","mehr_zur_auswahl":["einiges","vieles und","gär nix"]},{"meine_frage":"tom & jerry","ne_andere_frage":"mickey maus","was_willst_du":"oder","mehr_zur_auswahl":["manches","einiges","vieles und","gär nix"]},{"meine_frage":"dick und doof","ne_andere_frage":"minnie muas","was_willst_du":"nichts","mehr_zur_auswahl":["gär nix"]}]

let result = data.reduce(function(obj, item){
  Object.keys(item).forEach(function(key){
    if(!obj[key]) obj[key] = [].concat(item[key])
    else {
       if(Array.isArray(item[key]))
         obj[key].push(...item[key])
       else
         obj[key].push(item[key]);
    }
  });
  return obj;
},{});
console.log([result]);

🌐
IBM
ibm.com › support › pages › apar › IT27270
IT27270: JSON PARSER ACCEPTS OBJECTS WITH DUPLICATE KEYS
The JSON parser and serializer will accept objects that have multiple keys with the same name. JSON objects with duplicate
Top answer
1 of 1
8
{ "dates & times":
    {
        "dates": [ "date01", "date02", "date03" ],
        "times": [ "150", "165", "180" ]
    }
}

No, don't do that. You take an explicit relationship in one data structure and make it implicit between two data structures. Instead, do:

{ "dates & times": [
    { "date": "2014-08-24", "time": "150" },
    { "date": "2014-08-24", "time": "165" },
    { "date": "2014-08-24", "time": "180" },
] }

Now the relationship is explicit, and you can iterate over the array more simply and safely than iterating over the keys. (Safely because, if a property is added to Object.prototype, it will show up as a key.)

for (var key in myObj){
    if (key == selUser){
        for (var date in myObj[key]["dates & times"]){
            console.log("Date: " + date + "; " + "weight: " + myObj[key]["dates & times"][date]);
            var dtTag = "<dt class=\"date\"><span>Date: </span>" + date + " </dt>";
            var ddTag = "<dd class=\"value\"><span>Time: </span>" + myObj[key]["dates & times"][date] + "</dd>";
            output.innerHTML += dtTag;
            output.innerHTML += ddTag;
        }
    } // if 
} // loop

This has a bit more going on than is totally necessary. The outer loop is superfluous, since we only actually do something for one key. The inner loop changes with our new data structure. Also, we can do a bit of reorganization to help performance a bit. We will also change the if statement into a guard clause to clarify the code path.

// Is this key in the object, and does it have the right property?
if(!myObj[selUser] || !myObj[selUser]["dates & times"]) { // return, throw error, whatever }

output.innerHTML += myObj[selUser]["dates & times"].map(function(el){
    console.log("Date: " + el.date + "; Time: " + el.time);
    var dtTag = "<dt class=\"date\"><span>Date: </span>" + el.date + "</dt>";
    var ddTag = "<dd class=\"value\"><span>Time: </span>" + el.time + "</dd>";

    return dtTag + ddTag;
}).join("");

This relies on a newer ES5 feature, so polyfill or replace with equivalent loops if you need to support older browsers (see below). Also, this code does not exactly give the output you specified, FYI.


Without Array#map:

// Is this key in the object, and does it have the right property?
if(!myObj[selUser] || !myObj[selUser]["dates & times"]) { // return, throw error, whatever }

var i, el, dtTag, ddTag;

var listItems = [];
var datesAndTimes = myObj[selUser]["dates & times"];
var datesAndTimesLength = datesAndTimes.length;

for(i = 0; i < datesAndTimesLength; i++) {
    el = datesAndTimes[i];
    console.log("Date: " + el.date + "; Time: " + el.time);
    dtTag = "<dt class=\"date\"><span>Date: </span>" + el.date + "</dt>";
    ddTag = "<dd class=\"value\"><span>Time: </span>" + el.time + "</dd>";

    listItems.push(dtTag + ddTag);
}

output.innerHTML += listItems.join("");
Top answer
1 of 6
4

You can use map like this :

EDIT

For handling generic keys you can use Object.keys(d)[0] for first key Object.keys(d)[1] for second key

var sample = [

     {
      "label":"one",
      "value":1
     },

     {
      "label":"two",
      "value":2
     },
     {
      "label":"three",
      "value":3
     },
     { 
      "label":"four",
      "value":4
     },
     { 
      "label":"five",
      "value":5
      }

     ];
    var data = sample.map(function(d){
     return {label: Object.keys(d)[0], value: Object.keys(d)[1], newKeyValue:  Object.keys(d)[0] +"|" + Object.keys(d)[1]}
    }) 
    console.log(data)

Hope this helps!

2 of 6
3

You can use Array#map(), Object.keys(), and Array#join().

In ES6, you can use Arrow functions.

sample = sample.map(obj => {
    var keys = Object.keys(obj);
    obj.newKeyValue = keys.map(key => obj[key]).join('|');
    return obj;
});

var sample = [{
    "label": "one",
    "value": 1
}, {
    "name": "two",
    "age": 2
}, {
    "five": "three",
    "six": 3
}, {
    "company": "four",
    "organization": 4
}, {
    "label": "five",
    "value": 5
}];

sample = sample.map(function (x) {
    var keys = Object.keys(x);
    x.newKeyValue = keys.map(key => x[key]).join('|');
    return x;
});
console.log(sample);
document.body.innerHTML = '<pre>' + JSON.stringify(sample, 0, 4) + '</pre>';

In ES5, you can use the same code with anonymous functions

sample = sample.map(function (obj) {
    var keys = Object.keys(obj);
    obj.newKeyValue = keys.map(function (key) {
        return obj[key]
    }).join('|');
    return obj;
});

Limitations due to dynamic keys:

  1. The order of the keys in object cannot be maintained
  2. This will join all the available keys in the object (in case if you just want to join fewer)
🌐
GitHub
github.com › nlohmann › json › issues › 612
How to parse multiple same Keys of JSON and save them? · Issue #612 · nlohmann/json
December 7, 2016 - I have several Objects in my JSON, something like this: { Id= 1 Name = David }, { Id = 2 Name = Katja }, { Id = 3 Name = Luka }, ... As you can see, I have several identifiers (Id, Name) which are the same in my JSON. How can I do this in C++ with this Lib, so that I can parse it only once ...
Published   Jun 08, 2017
🌐
EyeHunts
tutorial.eyehunts.com › home › merge two json objects with same key javascript | example code
Merge two JSON objects with same key JavaScript | Code
November 16, 2022 - Using Nested for loop you can Merge two JSON objects with the same key JavaScript. Or You could use Map and Object.assign for merging objects
Find elsewhere
Top answer
1 of 3
1

You can do:

const data = {data: [{name: 'A',description: {location: 'location1',floor: 'floor1',},},{name: 'A',description: {location: 'location2',floor: 'floor1',},},{name: 'B',description: {location: 'location3',floor: 'floor3',},},],}

const result = {
  data: data.data.reduce((a, { name, description }) => {
    const index = a.findIndex((d) => d.name === name)
    if (index >= 0) {
      let location = a[index].description.location
      location = Array.isArray(location) ? location : [location]
      a[index].description.location = [...location, description.location]
    } else {
      a.push({ name, description })
    }
    return a
  }, []),
}

console.log(result)

2 of 3
1

const list = {
    "data": [
        {
            "name": "A",
            "description": {
                "location": "location1",
                "floor": "floor1",
            },
        },
        {
            "name": "A",
            "description": {
                "location": "location2",
                "floor": "floor1",
            },
        },
        {
            "name": "B",
            "description": {
                "location": "location3",
                "floor": "floor3",
            },
        },
    ]
};


const consolidatedData = [];

for (const ele of list.data) {
    const isExist = consolidatedData.find(x => x.name === ele.name);

    if (!isExist) {
        consolidatedData.push({
            ...ele
        })
    } else {
        const objectKey = consolidatedData.findIndex(x => x.name === ele.name);
        if (objectKey > -1) {
            const description = consolidatedData[objectKey].description;
            const newDes = ele.description;

            if (newDes.location !== description.location) {
                const data = consolidatedData[objectKey].description;
                const added = [data.location, ele.description.location];
                delete consolidatedData[objectKey].description.location
                consolidatedData[objectKey].description["location"] = added
            }

            if (newDes.floor !== description.floor){
                const data = consolidatedData[objectKey].floor;
                const added = [data.floor, ele.description.floor];
                delete consolidatedData[objectKey].description.floor
                consolidatedData[objectKey].description["floor"] = added
            }

        }
    }
}

console.log(JSON.stringify(consolidatedData, null, 2));

🌐
Esdiscuss
esdiscuss.org › topic › json-duplicate-keys
JSON Duplicate Keys
If a key is duplicated, a parser SHOULD reject. is not a change. It is implied by the first statement. The thing that is a change is the third statement · If it does not reject, it MUST take only the last of the duplicated ... On 6/6/2013 4:34 AM, Anne van Kesteren wrote: > On Thu, Jun 6, ...
Top answer
1 of 5
3

You can use first Array.reduce() to group the companies by the module key on a Set. On a second step you can use array.Map() over the generated object .entries() to get the final desired result:

const data = [
   {module: "credit_cards", id: "1", company: "ABC", prod: "1"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "credit_cards", id: "3", company: "EFG", prod: "2"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "mortgages", id: "4", company: "EFG", prod: "3"}
];

let res = data.reduce((acc, {module, company}) =>
{
    acc[module] = acc[module] || new Set();
    acc[module].add(company);
    return acc;
}, {})

res = Object.entries(res).map(
    ([module, companies]) => ({module, company: [...companies]})
);

console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}

2 of 5
3

Reduce into an object indexed by module, then take that object's values. Because you only want unique company values, use a Set initially, and then transform all items' company sets back into an array afterwards:

const data = [
   {module: "credit_cards", id: "1", company: "ABC", prod: "1"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "credit_cards", id: "3", company: "EFG", prod: "2"}, 
   {module: "credit_cards", id: "2", company: "XYZ", prod: "2"}, 
   {module: "mortgages", id: "4", company: "EFG", prod: "3"}
]

const result = Object.values(data.reduce(
  (a, { module, company }) => {
    if (!a[module]) a[module] = { module, company: new Set() };
    a[module].company.add(company);
    return a;
  },
  {}
));

result.forEach((item) => {
  item.company = [...item.company];
});
console.log(result);

🌐
Reddit
reddit.com › r/learnpython › assistance parsing nested json with multiple keys named the same!
r/learnpython on Reddit: Assistance parsing nested json with multiple keys named the same!
December 13, 2023 -

Hi - I'm quite new to python and attempting to parse some json, reasonably unsuccessfully at the moment. I have the following structure:

json_data = {
"struct": [[
    {
        "struct": "car",
        "points": {
            "brand": "tesla",
            "points": {
                "engine_size": "electric",
                "doors": "2",
                "points": {
                    "colour": "83922",
                }
            }
        }
    },
    {
        "struct": "house",
        "points": {
            "house_type": "semi",
            "windows": "6"
        }
    },
    {
        "struct": "garden",
        "points": {
            "garden_type": "small"
        }
    }
]]

}

For each structure or 'struct' I'm trying to pull out only the points, but not nested points if that makes sense? So the end results should print out:
{'brand': 'tesla', 'points'}
{'engine_size': 'electric', 'doors': '2'}
{'colour': '83922'}
{'house_type': 'semi', 'windows': '6'}
{'garden_type': 'small'}

I can parse some of this quite easily, but i am struggling with the car details. The best i can get is :
{'brand': 'tesla', 'points': {'engine_size': 'electric', 'doors': '2', 'points': {'colour': '83922'}}}
{'engine_size': 'electric', 'doors': '2', 'points': {'colour': '83922'}}
{'colour': '83922'}
{'house_type': 'semi', 'windows': '6'}
{'garden_type': 'small'}
But i dont want the nested points - i need each 'points' separate, my working code right now is:

def print_points(data):
if isinstance(data, dict):
    for key, value in data.items():
        if key == 'points':
            print(value)
            print_points(value)
        else:
            print_points(value)
elif isinstance(data, list):
    for item in data:
        print_points(item)

print_points(json_data)

Can anyone offer any suggestions / articles / guidance as to how I can learn how to do this? I'm not very good with data structures yet!