Modifying a JSON Object - javascript

I have a JSON generated by Papa Parse from a CSV file that look like this:
{ object, object, object, .... , object }
I need to modify it so it looks like this:
{ "publication" :
{
"id" : 1,
"name" : "name1"
},
"publication" :
{
"id" : 2,
"name" : "name2"
},
"publication" :
{
"id" : 3,
"name" : "name3"
}
}
Where the "id" and "name" are properties within each object.
In other words, I need a JSON that say "publication" and each "publication" occurrence have nested under it the properties names and values of one of the objects above.
How could I achieve this with Javascript?
Thanks

you cannot put many keys with same name...
a solution it's put in array
{
"publication" : [
{
"id" : 1,
"name" : "name1"
},
{
"id" : 2,
"name" : "name2"
},
{
"id" : 3,
"name" : "name3"
}]
}

Is this not an array of publications?
{ publications: [{"id":1, "name":"name1"},
{"id":2, "name":"name2"}.....]}

If I understand it right, you probably mean that you have objects like this:
{"publication" : { "id" : 1, "name" : "name1" }
{"publication" : { "id" : 2, "name" : "name2" }
{"publication" : { "id" : 3, "name" : "name3" }
What you can do in order to have:
{ "publication" : [
{
"id" : 1,
"name" : "name1"
},
{
"id" : 1,
"name" : "name2"
},
{
"id" : 3,
"name" : "name3"
} ]
}
is:
var json = [{"publication" : { "id" : 1, "name" : "name1" }},
{"publication" : { "id" : 2, "name" : "name2" }},
{"publication" : { "id" : 3, "name" : "name3" }}];
var newJson = {"publication" : []};
var i = 0;
for (var item in json) {
var key = json[item];
var obj = {"id" : key["publication"]["id"], "name" : key["publication"]["name"]};
newJson["publication"][i] = obj;
i++;
}
You can check this if you want to print "pretty":
How can I pretty-print JSON using JavaScript?

Related

List of array with different keys in a unique array Javascript

I am iterating data from a JSON file that I previousy fetch with the following code:
getData().then(data => {
for (const key in data) {
if (data.hasOwnProperty(key)) {
// do something with the data
}
}
}
The json file is very long, but it look something like this:
{
"01": {
"id" : "01",
"title" : "example1",
"size" : "100",
"pictures" : []
},
"02": {
"id" : "02",
"title" : "example2",
"size" : "0",
"pictures" : []
},
"03": {
"id" : "03",
"title" : "example3",
"size" : "300",
"pictures" : [
{ "pic_name1" : "example_pic1", "source" : "http://example.pic/1234" },
{ "pic_name2" : "example_pic2", "source" : "http://example.pic/4321" },
]
},
}
Now, to create a function that will filter through my data I need to put all of the size in a separate array (that I will later work with) and I tried this (inside the IF condition)
let sizes = new Array(data[key].size);
What I need to return is an array, but I get instead a list of array for each size:
["100"]["0"]["300"]...
How do I return a single array with all sizes as a list?
Simply map over each value and pluck the size. E.g.
const data = {
"01": {
"id" : "01",
"title" : "example1",
"size" : "100",
"pictures" : []
},
"02": {
"id" : "02",
"title" : "example2",
"size" : "0",
"pictures" : []
},
"03": {
"id" : "03",
"title" : "example3",
"size" : "300",
"pictures" : [
{ "pic_name1" : "example_pic1", "source" : "http://example.pic/1234" },
{ "pic_name2" : "example_pic2", "source" : "http://example.pic/4321" },
]
},
};
const sizes = Object.values(data).map(({size}) => size);
console.log(sizes);
Using ES8 new features inside the if condition,
let sizes = Object.values(data).map(({size}) => size);

How to update the values of a "Key-Value" pair in a nested array in MongoDB without adding a new element

I have the following data:-
**{
"_id" : ObjectId("5bf8048768d1e82d8bb4a477"),
"customer_code" : "c100003",
"vm_info" : [
{
"instanceId" : "i-0495d75742b839858",
"tags" : [
{
"Key" : "SIDs",
"Value" : "NWS"
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OS_VERSION",
"Value" : "10"
}
]
},
{
"instanceId" : "i-017488cffca28cd70",
"tags" : [
{
"Key" : "OS_VERSION",
"Value" : "10"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "SIDs",
"Value" : "NWS"
}
]
},
{
"instanceId" : "i-09d5db81657fe35d8",
"tags" : [
{
"Key" : "SIDs",
"Value" : "NWS"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "OS_VERSION",
"Value" : "10"
}
]
}
]
}**
Now i want to update the value of "OS_VERSION" to "12" instead of "10". After updating it should look like this:-
**{
"_id" : ObjectId("5bf8048768d1e82d8bb4a477"),
"customer_code" : "c100003",
"vm_info" : [
{
"instanceId" : "i-0495d75742b839858",
"tags" : [
{
"Key" : "SIDs",
"Value" : "NWS"
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OS_VERSION",
"Value" : "12"
}
]
},
{
"instanceId" : "i-017488cffca28cd70",
"tags" : [
{
"Key" : "OS_VERSION",
"Value" : "10"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "SIDs",
"Value" : "NWS"
}
]
},
{
"instanceId" : "i-09d5db81657fe35d8",
"tags" : [
{
"Key" : "SIDs",
"Value" : "NWS"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "OS_VERSION",
"Value" : "10"
}
]
}
]
}**
When i use Update operator with "$addToSet" a new Key-Value pair is added instead of updating the existing data like this:
**{
"_id" : ObjectId("5bf8048768d1e82d8bb4a477"),
"customer_code" : "c100003",
"vm_info" : [
{
"instanceId" : "i-0495d75742b839858",
"tags" : [
{
"Key" : "SIDs",
"Value" : "NWS"
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OS_VERSION",
"Value" : "10"
},
{
"Key" : "OS_VERSION",
"Value" : "12"
}
]
}
]
}** I don't want it to be added as a new element ,instead it should just update the existing element.
How can i achieve the desired result. Can someone help on this.
first remove that key-value pair and and insert new one.

Concatenate object's properties of variable length of a JavaScript object into a new property of the object

I have this complicated object structure:
myObject = {
"myObject" : [
{
"id" : 1,
"parameters" : [
{
"name" : "name1",
"special" : "xxx"
},
{
"name" : "name2",
"special" : "yyy"
}
]
},
{
"id" : 2,
"parameters" : [
{
"name" : "name3",
"special" : "zzz"
}
]
},
{
"id" : 2,
"parameters" : [
{
"name" : "name4",
"special" : "ttt"
},
{
"name" : "name5",
"special" : "aaa"
},
{
"name" : "name6",
"special" : "zzz"
}
]
},
...
]
};
It consists of a array of other objects, each of them having a variable number of parameters.
My goal is to concatenate the special of parameters of each object into a new string which must be stored as new property of it.
In this case, the result should look like:
myObject = {
"myObject" : [
{
"id" : 1,
"parameters" : [
{
"name" : "name1",
"special" : "xxx"
},
{
"name" : "name2",
"special" : "yyy"
}
],
"newProp" : "xxxyyy"
},
{
"id" : 2,
"parameters" : [
{
"name" : "name3",
"special" : "zzz"
}
],
"newProp" : "zzz"
},
{
"id" : 2,
"parameters" : [
{
"name" : "name4",
"special" : "ttt"
},
{
"name" : "name5",
"special" : "aaa"
},
{
"name" : "name6",
"special" : "zzz"
}
],
"newProp" : "tttaaazzz"
},
...
]
};
I tried something like this:
forEach(arr in myObject.myObject){
arr.parameters(forEach (i in arr.parameters.special) {
myObject.myObject = i.concat(myObject.myObject);
})
}
obviously, it does not work. But I guess that this could be the right approach.
Any suggestions?
You can loop through the object using Array#forEach and then construct the string based on parameter values using Array#map and Array#join, like this:
const myObject = {"myObject":[{"id":1,"parameters":[{"name":"name1","special":"xxx"},{"name":"name2","special":"yyy"}]},{"id":2,"parameters":[{"name":"name3","special":"zzz"}]},{"id":2,"parameters":[{"name":"name4","special":"ttt"},{"name":"name5","special":"aaa"},{"name":"name6","special":"zzz"}]}]};
myObject.myObject.forEach(item => {
item.newProp = item.parameters.map(p => p.special).join('');
});
console.log(myObject);
Use reduce and for Each
var myObject = {
"myObject" : [
{
"id" : 1,
"parameters" : [
{
"name" : "name1",
"special" : "xxx"
},
{
"name" : "name2",
"special" : "yyy"
}
]
},
{
"id" : 2,
"parameters" : [
{
"name" : "name3",
"special" : "zzz"
}
]
},
{
"id" : 2,
"parameters" : [
{
"name" : "name4",
"special" : "ttt"
},
{
"name" : "name5",
"special" : "aaa"
},
{
"name" : "name6",
"special" : "zzz"
}
]
}
]
};
myObject.myObject.forEach(arr => {
arr.prop = arr.parameters.reduce((res,obj)=> res+obj.special, '')
})
console.log(myObject)
You can use .map() and .reduce() like this:
let myObject = [{"id" : 1, "parameters" : [{ "name" : "name1", "special" : "xxx"}, { "name" : "name2", "special" : "yyy" }]}, { "id" : 2, "parameters" : [{ "name" : "name3", "special" : "zzz"}]}, {"id" : 2, "parameters" : [{ "name" : "name4", "special" : "ttt"}, { "name" : "name5", "special" : "aaa"},{ "name" : "name6", "special" : "zzz"}]}];
let result = myObject.map(
o => (o.newProp = o['parameters'].reduce((a, o) => a + o['special'], ""), o)
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
One more way is to use nested map functions:
myObject = {"myObject":[{"id":1,"parameters":[{"name":"name1","special":"xxx"},{"name":"name2","special":"yyy"}]},{"id":2,"parameters":[{"name":"name3","special":"zzz"}]},{"id":2,"parameters":[{"name":"name4","special":"ttt"},{"name":"name5","special":"aaa"},{"name":"name6","special":"zzz"}]}]};
myObject.myObject.map(x => {
x.newProp = x.parameters.map(p => p.special).join('');
return x;
})
console.log(myObject);

cannot use the part (stats of stats.cat3.detail.name) to traverse the element. nested objects and arrays

I'm able to do
db.getCollection('comps').find({"stats.cat3.detail.name" : "Friendlyness"})`
This shows the proper docs the have a name of "Friendlyness" in the detail array.
I wanted to change "Friendlyness" to "friendliness"
I tried :
db.getCollection('comps').update(
{"stats.cat3.detail.name" : "Friendlyness"},
{$set : {"stats.cat3.detail.name" : "Friendliness"} }
)
and got errors like
" cannot use the part (stats of stats.cat3.detail.name) to traverse the element ({stats: [ { cat3: ...."
I tried putting in position operators "$" all over the update object property. but still get errors.
sample data:
{
"_id" : ObjectId("58d94c441eb9e52454932db6"),
"desc" : "Manufacturer of a wide range of consumer electronics products including audio, video, communications, and computer systems.",
"source" : "alexa",
"category" : "Consumer Electronics",
"name" : "comp1.com",
"__v" : 0,
"stats" : [
{
"cat1" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "quick service"
}
],
"name" : "Time on hold"
},
{
"value" : [
{
"data" : 1,
"name" : "some words but strong accent"
},
{
"data" : 1,
"name" : "EZ to understand"
}
],
"name" : "Language fluency"
},
{
"value" : [
{
"data" : 1,
"name" : "Yes"
}
],
"name" : "Human answered"
},
{
"value" : [
{
"data" : 2,
"name" : "Like a hot potato"
},
{
"data" : 1,
"name" : "1 or 2 times"
}
],
"name" : "Transfered alot"
},
{
"value" : [
{
"data" : 3,
"name" : "ok time"
},
{
"data" : 1,
"name" : "quick service"
},
{
"data" : 1,
"name" : "short time"
}
],
"name" : "Time on Hold"
},
{
"value" : [
{
"data" : 1,
"name" : "some word but strong accent"
},
{
"data" : 2,
"name" : "EZ to understand"
}
],
"name" : "Language Fluency"
},
{
"value" : [
{
"data" : 2,
"name" : "Yes"
}
],
"name" : "Human Answered"
}
],
"average" : 81
},
"cat2" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "It was ok"
},
{
"data" : 1,
"name" : "Not EZ at all"
},
{
"data" : 7,
"name" : "there were hidden gimicks"
},
{
"data" : 2,
"name" : "It was OK"
},
{
"data" : 1,
"name" : "Found Quickly"
}
],
"name" : "Easy to find desired product"
},
{
"value" : [
{
"data" : 1,
"name" : "Easy to understand"
},
{
"data" : 1,
"name" : "Eventually understood"
}
],
"name" : "Clear information about the product"
},
{
"value" : [
{
"data" : 2,
"name" : "none"
},
{
"data" : 3,
"name" : "There was but won't complain"
},
{
"data" : 1,
"name" : "Very Bad"
}
],
"name" : "Annoying popups"
},
{
"value" : [
{
"data" : 4,
"name" : "Eventually Understood"
},
{
"data" : 1,
"name" : "EZ to understand"
}
],
"name" : "Clear data about the product"
}
],
"average" : 71
},
"cat3" : {
"detail" : [
{
"value" : [
{
"data" : 1,
"name" : "Very quick"
}
],
"name" : "Prompteness"
},
{
"value" : [
{
"data" : 3,
"name" : "We're cool"
},
{
"data" : 4,
"name" : "They didn't like me"
}
],
"name" : "Friendlyness"
},
{
"value" : [
{
"data" : 3,
"name" : "Very Confusing"
},
{
"data" : 2,
"name" : "Still a little confused"
},
{
"data" : 3,
"name" : "Enlightened"
}
],
"name" : "Knowledge"
},
{
"value" : [
{
"data" : 3,
"name" : "On hold too many times"
}
],
"name" : "Promptness"
}
],
"average" : 69
}
}
]
}

unable to "skip" mongoose sub-documents

I am using mongoose and node and I am trying to paginate data from sub-documents. I am able to limit subdocuments, but not skip them.
The versions I am using are:
Mongo 3.0.0
Node 0.10.33
Mongoose 3.9.7
The Data
[{
"name" : "Ranger Table",
"_id" : ObjectId("550234d3d06039d507d238d8"),
"body" : [
{
"name" : "Jason",
"colour" : "Red",
"animal" : "T-rex",
"_id" : ObjectId("550234d3d06039d507d238de")
},
{
"name" : "Billy",
"colour" : "Blue",
"animal" : "Triceratops",
"_id" : ObjectId("550234d3d06039d507d238dd")
},
{
"name" : "Zach",
"colour" : "Black",
"animal" : "Mastadon",
"_id" : ObjectId("550234d3d06039d507d238dc")
},
{
"name" : "Tommy",
"colour" : "Green",
"animal" : "Dragon"
"_id" : ObjectId("550234d3d06039d507d238d9")
}
]
},{
"name" : "Bot Table",
"_id" : ObjectId("5502d205184cd74033f64e6b"),
"body" : [
{
"name" : "Optimus",
"team" : "Autobots",
"class" : "Leader",
"_id" : ObjectId("550234d3d06039d507d238d9")
},
{
"name" : "Bumblebee",
"team" : "Autobots",
"class" : "Scout",
"_id" : ObjectId("550234d3d06039d507d238da")
},
{
"name" : "Astrotrain",
"team" : "Decepticons",
"class" : "Transport",
"_id" : ObjectId("550234d3d06039d507d238db")
}
]
}]
The Code
var BodySchema = new Schema({random: String},{strict:false});
var FeedSchema = new Schema({
name: String,
body:[BodySchema]
});
var feed = mongoose.model('Feed', FeedSchema);
feed.find({_id:'550234d3d06039d507d238d8'})
.populate({
"path":"body",
"options":{
limit:2, //This works fine
skip:2 //This doesn't work
}
})
.exec(function(err, result){
if(err){return(res.send(500, err))}
res.send(result);
});
The Result
The above code DOES limit the number of "body" sub-documents to 2, but doesn't skip any.
The code above returns this:
{
"name" : "Ranger Table",
"_id" : ObjectId("550234d3d06039d507d238d8"),
"body" : [
{
"name" : "Jason",
"colour" : "Red",
"animal" : "T-rex",
"_id" : ObjectId("550234d3d06039d507d238de")
},
{
"name" : "Billy",
"colour" : "Blue",
"animal" : "Triceratops",
"_id" : ObjectId("550234d3d06039d507d238dd")
}
]
}
But it should return this:
{
"name" : "Ranger Table",
"_id" : ObjectId("550234d3d06039d507d238d8"),
"body" : [
{
"name" : "Zach",
"colour" : "Black",
"animal" : "Mastadon",
"_id" : ObjectId("550234d3d06039d507d238dc")
},
{
"name" : "Tommy",
"colour" : "Green",
"animal" : "Dragon"
"_id" : ObjectId("550234d3d06039d507d238d9")
}
]
}
The solution that I found was to use aggregate and specify the name of the subdocument with $unwind.
http://docs.mongodb.org/manual/reference/operator/aggregation/
feed.aggregate([
{'$match':{_id:id('550234d3d06039d507d238d8')}},
{'$unwind':'$body'},
{'$skip':2},
{'$limit':2},
], function(err, result){
if(err){return(res.send(500, err))}
res.send(result);
});

Categories