How to take in key/value pair values of groovy map and loop into JSON array elements in groovy?.
For example:
Input:
def childmap = ["data1": "123", "data2": "234", "data3": "456"]
def childmap2= ["data4": "123", "data5": "234", "data6": "456","date7":"676"]
def parentmap= ["Key1":"Value1","Key2":"Value2","Key3":childmap,"key4":childmap2]
Expected JSON Output:
{
"Json":{
"Key1":"Value1",
"Key2":"Value2"
"key3":[
{
"Name": "data1",
"ID": "123"
},
{
"Name": "data2",
"ID": "234"
},
{
"Name": "data3",
"ID": "456"
}
],
"key4":[
{
"Name": "data4",
"ID": "123"
},
{
"Name": "data5",
"ID": "123"
},
{
"Name": "data6",
"ID": "234"
},
{
"Name": "data7",
"ID": "456"
}
]
}
}
This works for your example. This won't work if you've got deeper nesting.
def newmap = parentmap.collectEntries { key, value ->
[key, (value instanceof Map) ? value.collect {key2, value2 -> [Name: key2, ID: value2]} : value]}
def builder = new JsonBuilder([Json : newmap])
println builder.toPrettyString()
Related
I wish to add data into Elements but get error. How to solve this mongodb/typescript problem?
Attempt 1 Error: No value exists in scope for the shorthand property 'elements'. Either declare one or provide an initializer.ts(18004)
Attempt 1
async add<T extends { id: string; parentID: string, elementNum: number, name: string, link: string}>(collectionName: string, args: T) {
const db = await this.getDB();
const collection = db.collection(collectionName);
return new Promise((resolve, reject) => {
collection.updateOne({ id: args.id }, {$push: {elements[args.elementNum]: {id: uuid(), name: args.name, link: args.link, elements: [] }}}, (err, res) => {
if (err) {
reject(err);
}
resolve(res);
});
});
}
Attempt 2
changed the following
collection.updateOne({ id: args.id }, {$push: {elements: {id: uuid(), name: args.name, link: args.link, elements: [] }}},
Attempt 2 results in Null added in the end
{
"id": "1",
"name": "wk1",
"iconFile": "icon.png",
"elements": [
[
{
"id": "2",
"name": "element2",
"link": "https",
"elements": [
{
"id": "1",
"name": "element1",
"link": "https:"
}
]
}
],
[
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
{
"id": "4",
"name": "w",
"link": "http:/"
}
]
}
],
[
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
{
"id": "4",
"name": "w",
"link": "http://"
}
]
},
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
{
"id": "4",
"name": "w",
"link": "http://www."
}
]
}
],
null,
]
}
What I want to achieve is the following
{
"id": "1",
"name": "wk1",
"iconFile": "icon.png",
"elements": [
[
{
"id": "2",
"name": "element2",
"link": "https",
"elements": [
{
"id": "1",
"name": "element1",
"link": "https:"
}
]
},
{
"id": "newid",
"name": "newname",
"link": "newlink"
"elements":[]
}
],
[
{
"id": "3",
"name": "element3",
"link": "https://",
"elements": [
.......
]
}
Demo - https://mongoplayground.net/p/Dnmg3lL2891
Use - $[]
The all positional operator $[] indicates that the update operator
should modify all elements in the specified array field.
The $[] operator has the following form:
{ <update operator>: { "<array>.$[]" : value } }
db.collection.update({ _id: 1, "add.id": "1"},
{ $push: { "add.$[].elements": { id: "3", name: "a", link: "" } } })
Demo to push array instead of object - https://mongoplayground.net/p/dh3NSutIv4-
db.collection.update({ _id: 1, "add.id": "1"},
{ $push: { "add.$[].elements": [{ id: "3", name: "a", link: "" }] } })
const args = {};
args.elementNum = 0;
const update = {
[`add.$[].elements.${args.elementNum}`]: {
a: 1
}
};
console.log(update);
//collection.updateOne({ id: args.id }, update); // use like this
First Array contains the below array of elements
"Data": [
{
"ID": 1,
"Name": "XYZ",
"Driver": "Assigned",
}
{
"ID": 2,
"Name": "PQR",
"Driver": "UnAssigned",
}
Second Array is of different set of data
"Data": [
{
"Updated": "KLM",
"Date": "22/01/2020",
}
{
"Updated": "PQR",
"Date": "23/01/2020",
}
{
"Updated": "OOO",
"Date": "23/07/2020",
}
I want the final json as below
"Data": [
{
"ID": 1,
"Name": "XYZ",
"Driver": "Assigned",
"Updated": "KLM",
"Date": "22/01/2020",
}
{
"ID": 2,
"Name": "PQR",
"Date": "23/01/2020",
"Updated": "PQR",
"Date": "23/01/2020",
}
{
"ID": 2,
"Name": "PQR",
"Driver": "UnAssigned",
"Updated": "PQR",
"Date": "23/01/2020",
}
{
"ID": "",
"Name": "",
"Driver": "",
"Updated": "OOO",
"Date": "23/07/2020",
}
If both the arrays are of different lengths, the field should go as blank like the last one. How can we do in reactjs
You need a zip like functionality available in Python.
I created the below snippet that should be of help.
const firstArray = [
{
ID: 1,
Name: "XYZ",
Driver: "Assigned",
},
{
ID: 2,
Name: "PQR",
Driver: "UnAssigned",
},
];
const secondArray = [
{
Updated: "KLM",
Date: "22/01/2020",
},
{
Updated: "PQR",
Date: "23/01/2020",
},
{
Updated: "OOO",
Date: "23/07/2020",
},
];
// get an empty object from first array with "" as values
firstSchema = Object.keys(firstArray[0]).reduce((acc, cur) => {
acc[cur] = "";
return acc;
}, {});
// get an empty object from second array with "" as values
secondSchema = Object.keys(secondArray[0]).reduce((acc, cur) => {
acc[cur] = "";
return acc;
}, {});
// create an empty schema object merged with both above schemas
emptySchema = { ...firstSchema, ...secondSchema };
const zip = (a, b) =>
Array.from(Array(Math.max(b.length, a.length)), (_, i) => ({
...emptySchema,
...a[i],
...b[i],
}));
console.log(zip(firstArray, secondArray));
Also, as user Explosion Pills commented above, you should maybe look into how your data is stored so you can have the ID key in the second data set too.
I have the following multidemensional array:
[
{
"city": {
"name": "New York",
"country": "Usa",
"geolocation": {
"lat": "40.7142691",
"lon": "-74.0059729"
},
},
"experiences": [
{
"title": "foobar",
"id": "54095f19ca04fffa8791ecae"
},
{
"title": "foobar_foo",
"id": "54e1bff02f16a457c00ea171"
}
[...]
]
},
{
"city": {
"name": "San Francisco",
"country": "Usa",
"geolocation": {
"lat": "37.7749295",
"lon": "-122.4194155"
},
},
"experiences": [
{
"title": "foobar",
"id": "53e4db618027d69eab65f2ce"
},
{
"title": "foobar_bar",
"id": "54afbeb7abdf8e3d30bd5993"
}
[...]
]
}
]
I need to create a new array filled with the IDs of each experience in the above array, something like:
["id" = "foo123", "id" => "foo456", "id" => "foo789", "id" => "fooabc"]
I've tried using laravel's helper Arr::pluck but it returns null:
Arr::pluck($myArr, "experiences.id")
[null, null, null]
How can I do this?
Try
$res = [];
foreach($data as $key => $value)
{
foreach($value['experiences'] as $exp)
{
$res[] = $exp['id'];
}
}
dd($res);
Output will be
array:4 [
0 => "54095f19ca04fffa8791ecae"
1 => "54e1bff02f16a457c00ea171"
2 => "53e4db618027d69eab65f2ce"
3 => "54afbeb7abdf8e3d30bd5993"
]
I need to build the following json using groovy's JsonBuilder().
[
{
"date": "2017-12-08",
"dog": [
{
"name": "Joe",
"age": "1"
},
{
"name": "Bro",
"age": "2"
},
{
"name": "Doe",
"age": "3"
}
]
}
]
I cant get the array in the array, because of the date, it wants to always to put date not in the same level as dog array, but put it in { }, like:
[{
{
"date": "2017-12-08",
},
"dog": [
{
"name": "Joe",
"age": "1"
},
{
"name": "Bro",
"age": "2"
},
{
"name": "Doe",
"age": "3"
}
]
}
]
Just stick the date alongside your list in the model:
import groovy.json.JsonBuilder
import groovy.transform.Canonical
#Canonical
class Dog {
int age
String name
}
#Canonical
class DogList {
String date
List<Dog> dog
}
def ark = [
new DogList('2017-12-08', [
new Dog(1, 'Joe'),
new Dog(2, 'Bro'),
new Dog(3, 'Doe')
])
]
def json = new JsonBuilder(ark).toPrettyString()
println json
prints:
[
{
"date": "2017-12-08",
"dog": [
{
"age": 1,
"name": "Joe"
},
{
"age": 2,
"name": "Bro"
},
{
"age": 3,
"name": "Doe"
}
]
}
]
I have a mongo collection called settings
{
"_id": "123",
"type": "subject",
"name": "Main",
"list": [{
"_id": "123",
"name": "Maths"
}, {
"_id": "123",
"name": " Physics"
}]
}
{
"_id": "123",
"type": "exam",
"name": "Activities",
"list": [{
"_id": "123",
"name": "Reading"
}, {
"_id": "123",
"name": "Fluency"
}]
}
Note: the values provided in my mongo is only for reference purpose.
Now I have generated an array with the records in settings collection
self.sample = function() {
self.settingsObj = {}
// console.log(self.settings)
_.each(self.settings, function(settings) {
//_.each(self.settings, function(settings) {
if (!self.settingsObj[settings.type]) {
self.settingsObj[settings.type] = []
}
self.settingsObj[settings.type] = settings.list
})
console.log(self.settingsObj)
}
When I console the settingsObj I get result like this in my console
Object {subject: Array[2], exam: Array[2]}
Now I want to loop this inside a scope variable
$scope.search = [{
"name": "",
"data": ""
}]
inside this name i want to get the object name in this situation subject,exam and inside loop i want to loop the arrays for subject and exam.
I tried another ._each, and I got the key and value but how can I loop them correctly.
Otherwise please help me in generating subject and exams as different array
I'm not very sure if I understand your question.
But if I see well you're using a Lodash.js library so I provide below script using a lodash:
I assume that you have settings variable like this:
var settings = [ {
"_id": "123",
"type": "subject",
"name": "Main",
"list": [{
"_id": "123",
"name": "Maths"
}, {
"_id": "123",
"name": " Physics"
}]
}
,
{
"_id": "123",
"type": "exam",
"name": "Activities",
"list": [{
"_id": "123",
"name": "Reading"
}, {
"_id": "123",
"name": "Fluency"
}]
}];
And I create functions for process those settings:
function createSearch(settings){
return _(settings).flatMap(toSearchArray).value();
}
function toSearchArray(setting){
return _(setting.list).map("name").map(toSearchObject).value()
function toSearchObject(data){
return {
name: setting.type,
data: data
}
}
}
And when you call createSearch(settings)
you will receive this result:
[
{
"name": "subject",
"data": "Maths"
},
{
"name": "subject",
"data": " Physics"
},
{
"name": "exam",
"data": "Reading"
},
{
"name": "exam",
"data": "Fluency"
}
]
Hopefully this is what you need.