create array on basis of object's child - javascript

I am have array like:
[
{
"_id": "62434e4c52a870a3840f40fd",
"Nome": [
{
"_id": "61f76c3c7a308dd136f1d33a",
"value": "Oo",
"updatedAt": "2022-05-04T00:00:00.000Z"
}
],
"Peso": [
{
"_id": "61f92ec87a308dd136c0e182",
"value": "554",
"updatedAt": "2022-05-04T00:00:00.000Z"
}
],
"createdAt": [
{
"value": "29/03/2022 03:22:02"
}
]
},
{
"_id": "62449de6ed196e40cb4309ae",
"Nome": [
{
"_id": "61f76c3c7a308dd136f1d33a",
"value": "Ssg",
"updatedAt": "2022-05-04T00:00:00.000Z"
}
],
"Peso": [
{
"_id": "61f92ec87a308dd136c0e182",
"value": "255",
"updatedAt": "2022-05-04T00:00:00.000Z"
}
],
"createdAt": [
{
"value": "29/03/2022 03:23:26"
}
]
},
],
What I'm having trouble with is loop between each object example Nome, Peso the names of these arrays are dynamic and do not have a static name!
Example of what I'm thinking:
[
{
"_id": "62434e4c52a870a3840f40fd",
"Nome": "Oo",
"Peso": "554",
"createdAt": "29/03/2022 03:22:02"
},
{
"_id": "62449de6ed196e40cb4309ae",
"Nome": "Ssg",
"Peso": "255",
"createdAt": "29/03/2022 03:23:26"
}
],
Thanks for help :D

If each Nome, Peso, createdAt property array always has one element, then you can use Array#map as follow:
const input = [ { "_id": "62434e4c52a870a3840f40fd", "Nome": [ { "_id": "61f76c3c7a308dd136f1d33a", "value": "Oo", "updatedAt": "2022-05-04T00:00:00.000Z" } ], "Peso": [ { "_id": "61f92ec87a308dd136c0e182", "value": "554", "updatedAt": "2022-05-04T00:00:00.000Z" } ], "createdAt": [ { "value": "29/03/2022 03:22:02" } ] }, { "_id": "62449de6ed196e40cb4309ae", "Nome": [ { "_id": "61f76c3c7a308dd136f1d33a", "value": "Ssg", "updatedAt": "2022-05-04T00:00:00.000Z" } ], "Peso": [ { "_id": "61f92ec87a308dd136c0e182", "value": "255", "updatedAt": "2022-05-04T00:00:00.000Z" } ], "createdAt": [ { "value": "29/03/2022 03:23:26" } ] } ];
const output = input.map(({_id,...rest}) => ({
_id,
...Object.fromEntries(
Object.entries(rest).map(([k,v]) => [k,v[0].value])
)
}));
console.log( output );

If considering those dynamic keys will have array then try below code.
const data = [{
"_id": "62434e4c52a870a3840f40fd",
"Nome": [{
"_id": "61f76c3c7a308dd136f1d33a",
"value": "Oo",
"updatedAt": "2022-05-04T00:00:00.000Z"
}],
"Peso": [{
"_id": "61f92ec87a308dd136c0e182",
"value": "554",
"updatedAt": "2022-05-04T00:00:00.000Z"
}],
"createdAt": [{
"value": "29/03/2022 03:22:02"
}]
},
{
"_id": "62449de6ed196e40cb4309ae",
"Nome": [{
"_id": "61f76c3c7a308dd136f1d33a",
"value": "Ssg",
"updatedAt": "2022-05-04T00:00:00.000Z"
}],
"Peso": [{
"_id": "61f92ec87a308dd136c0e182",
"value": "255",
"updatedAt": "2022-05-04T00:00:00.000Z"
}],
"createdAt": [{
"value": "29/03/2022 03:23:26"
}]
},
];
data.map(d => {
Object.keys(d).forEach(k => {
if (Array.isArray(d[k]) && d[k].length > 0)
d[k] = d[k][0].value;
});
});
console.log(data);

The below may be one possible solution to achieve the desired objective.
Code Snippet
const transformArr = arr => (
arr.map(obj => ({
...Object.fromEntries(
Object.entries(obj)
.map(([k, v]) => {
if (v && v.length > 0 &&
Array.isArray(v) &&
"value" in v[0]
) {
return [k, v[0].value]
} else {
return [k, v]
}
})
)
}))
);
const origArr = [
{
"_id": "62434e4c52a870a3840f40fd",
"Nome": [
{
"_id": "61f76c3c7a308dd136f1d33a",
"value": "Oo",
"updatedAt": "2022-05-04T00:00:00.000Z"
}
],
"Peso": [
{
"_id": "61f92ec87a308dd136c0e182",
"value": "554",
"updatedAt": "2022-05-04T00:00:00.000Z"
}
],
"createdAt": [
{
"value": "29/03/2022 03:22:02"
}
]
},
{
"_id": "62449de6ed196e40cb4309ae",
"Nome": [
{
"_id": "61f76c3c7a308dd136f1d33a",
"value": "Ssg",
"updatedAt": "2022-05-04T00:00:00.000Z"
}
],
"Peso": [
{
"_id": "61f92ec87a308dd136c0e182",
"value": "255",
"updatedAt": "2022-05-04T00:00:00.000Z"
}
],
"createdAt": [
{
"value": "29/03/2022 03:23:26"
}
]
},
];
console.log(transformArr(origArr));
Explanation
Iterate over the array
Use Object.entries() and Object.fromEntries() to extract key-value [k, v]pairs (as arrays) and then re-create (key-value pairs array back into an) object
Check if v is an array and that it has an element at index-0 with a prop value
If yes, then transform it to show only the value (of index-0 element)
Otherwise, just return v as-is
Constraint
If the inner-array (for "Nome", "Peso" or other "dynamic keys") has more than one element only the value from index-0 element will be considered.
NOTE
This solution does not mutate the original-array. It creates a new copy & if needed this may be re-assigned to the original-array.

Related

Filtering on nested array of objects to return the entire matching object

My array of nested objects looks like this along with the array to match it with
let findThis = ["Water"];
let arrayOfElements =
[
{
"code": "a",
"templates": [
{
"templateCode": "Water",
"title": "Earth"
},
{
"templateCode": "Milk",
"title": "Sky"
}
]
},
{
"code": "b",
"templates": []
},
{
"code": "c",
"templates": [
{
"templateCode": "Water",
"title": "Earth"
},
{
"templateCode": "Tree",
"title": "Moon"
}
},
{
"code": "d",
"templates": [
{
"templateCode": "Tooth",
"title": "Tiger"
}
}
]
I want to extract those objects whose templateCode is Water. So my final returned array should look like this.
let result =
[
{
"code": "a",
"templates": [
{
"templateCode": "Water",
"title": "Earth"
},
{
"templateCode": "Milk",
"title": "Sky"
}
]
},
{
"code": "c",
"templates": [
{
"templateCode": "Water",
"title": "Earth"
},
{
"templateCode": "Tree",
"title": "Moon"
}
}
]
I tried:
arrayOfElements.filter(x => x.templates.filter(y => findThis.includes(y.templateCode)));
But it is returning the entire array itself and is not working.
You need to filter the arrayOfElements with the condition of any templateCode existing inside the findThis array.
let findThis = ["Water"];
let arrayOfElements =
[
{
"code": "a",
"templates": [
{
"templateCode": "Water",
"title": "Earth"
},
{
"templateCode": "Milk",
"title": "Sky"
}
]
},
{
"code": "b",
"templates": []
},
{
"code": "c",
"templates": [
{
"templateCode": "Water",
"title": "Earth"
},
{
"templateCode": "Tree",
"title": "Moon"
}
]
},
{
"code": "d",
"templates": [
{
"templateCode": "Tooth",
"title": "Tiger"
}
]
}
]
const result = arrayOfElements.filter(item => item.templates.some(t => findThis.includes(t.templateCode)))
console.log(result)

Filter document on items in an array ElasticSearch using Where In

I have data:
[
{
"NAME": "John Doe",
"CLASS":[1,10,30]
},
{
"NAME": "Albert",
"CLASS": [1,20,40]
},
{
"NAME": "XINN",
"CLASS": [10,30]
},
{
"NAME": "UJANG",
"CLASS": [20,40]
},
{
"NAME": "BAMBANG",
"CLASS": [30,40]
}
]
I have the following query SQL:
SELECT * FROM table_name WHERE CLASS IN (1,20)
and I want what will appear is:
[{"NAME": "John Doe","CLASS":[1,10,30]},{"NAME": "Albert","CLASS": [1,20,40]},{"NAME": "UJANG","CLASS": [20,40]}]
How do I change my search to match the SQL query?
You can use the terms query to get your expected results, adding a working example.
Index sample docs
{
"name" : "John Doe",
"class" : [1, 10,30]
}
{
"name": "Albert",
"class": [1,20,40]
}
{
"name": "XINN",
"class": [10,30]
}
{
"name": "UJANG",
"class": [20,40]
}
{
"name": "BAMBANG",
"class": [30,40]
}
And search query
{
"query": {
"terms": {
"class": [
1,20
]
}
}
}
And search results
"hits": [
{
"_index": "shingleside",
"_type": "_doc",
"_id": "1",
"_score": 1.0,
"_source": {
"name": "John Doe",
"class": [
1,
10,
30
]
}
},
{
"_index": "shingleside",
"_type": "_doc",
"_id": "2",
"_score": 1.0,
"_source": {
"name": "Albert",
"class": [
1,
20,
40
]
}
},
{
"_index": "shingleside",
"_type": "_doc",
"_id": "4",
"_score": 1.0,
"_source": {
"name": "UJANG",
"class": [
20,
40
]
}
}
]

How to return an array hits from msearch

I've got an elasticsearch cluster I'm running a search against multiple indices (msearch) which returns an array of objects (one object for each index being queried). Each of these objects has an array of hits inside of a hits object. I'm really only after the _source object. How would you go about getting an array of all the nested "_source" objects?
[
{
"hits": {
"hits": [
{
"_index": "index1",
"_type": "type1",
"_id": "1",
"_score": 12.163426,
"_source": {
"somekey": "some value",
"someotherkey": "another value"
}
}
]
},
},
{
"hits": {
"hits": []
},
},
{
"hits": {
"hits": [
{
"_index": "index2",
"_type": "type2",
"_id": "2",
"_score": 7.0380797,
"_source": {
"somekey": "some value",
"someotherkey": "another value"
}
},
{
"_index": "index2",
"_type": "type2",
"_id": "3",
"_score": 6.07253,
"_source": {
"somekey": "some value 2",
"someotherkey": "another value 2"
}
}
]
},
},
]
You may use Array.prototype.flatMap() to traverse your outer array and Array.prototype.map() to turn hits.hits into array of _source properties as items:
const src = [{"hits":{"hits":[{"_index":"index1","_type":"type1","_id":"1","_score":12.163426,"_source":{"somekey":"some value","someotherkey":"another value"}}]},},{"hits":{"hits":[]},},{"hits":{"hits":[{"_index":"index2","_type":"type2","_id":"2","_score":7.0380797,"_source":{"somekey":"some value1","someotherkey":"another value1"}},{"_index":"index2","_type":"type2","_id":"3","_score":6.07253,"_source":{"somekey":"some value 2","someotherkey":"another value 2"}}]},},],
result = src.flatMap(o => o.hits.hits.map(({_source}) => _source))
console.log(result)
.as-console-wrapper{min-height:100%;}
you can reduce the objects:
const src = [
{
"hits": {
"hits": [
{
"_index": "index1",
"_type": "type1",
"_id": "1",
"_score": 12.163426,
"_source": {
"somekey": "some value",
"someotherkey": "another value"
}
}
]
},
},
{
"hits": {
"hits": []
},
},
{
"hits": {
"hits": [
{
"_index": "index2",
"_type": "type2",
"_id": "2",
"_score": 7.0380797,
"_source": {
"somekey": "some value",
"someotherkey": "another value"
}
},
{
"_index": "index2",
"_type": "type2",
"_id": "3",
"_score": 6.07253,
"_source": {
"somekey": "some value 2",
"someotherkey": "another value 2"
}
}
]
},
},
];
console.log(src.reduce((prev, el) => [...prev, ...el.hits.hits.map(o => o['_source'])], []))

I have a mongodb data response like the output below and want to group the results of the array field

I have a mongodb data response like the output below and want to group the results of the array field studentsTakingSubject by the dateStarted and then a count of studentId in the corresponding month but all my efforts have not worked. Please I need help
{
"data": {
"getSubjectPerformanceAnalysis": [
{
"_id": "5f11d2f4a40eff3f6af5ac31",
"teacherAssigned": "5ecfb15a6b60d08d688fd519",
"subjectName": "English",
"term": "third",
"classId": "5ef9fbcbcd7361513a423393",
"code": "Sub-686c0d",
"createdAt": "2020-07-17T16:33:56.029Z",
"updatedAt": "2020-07-31T14:35:25.574Z",
"__v": 0,
"studentsTakingSubject": [
{
"_id": "5f2424c7da6c6c344362d633",
"studentId": "5f1583c488fbd82308e86e37",
"dateStarted": "2020-07-31T13:53:26.000Z",
"updatedAt": "2020-07-31T14:03:51.590Z",
"createdAt": "2020-07-31T14:03:51.590Z"
},
{
"_id": "5f242570da6c6c344362d636",
"studentId": "5f11d1d0a40eff3f6af5ac2e",
"dateStarted": "2020-07-31T13:53:26.000Z",
"updatedAt": "2020-07-31T14:06:40.298Z",
"createdAt": "2020-07-31T14:06:40.298Z"
},
{
"_id": "5f2426ffda6c6c344362d63d",
"studentId": "5f199749aa89b14929b68c39",
"dateStarted": "2020-06-19T13:53:26.000Z",
"updatedAt": "2020-07-31T14:13:19.580Z",
"createdAt": "2020-07-31T14:13:19.580Z"
},
{
"_id": "5f242c2df97301390dc90b3e",
"studentId": "5f199749aa89b14929b68c39",
"dateStarted": "2020-06-19T13:53:26.000Z",
"updatedAt": "2020-07-31T14:35:25.574Z",
"createdAt": "2020-07-31T14:35:25.574Z"
}
]
}
]
}
}
I need an output like this
[
{
"_id": "01",
"count": 1
},
{
"_id": "02",
"count": 5
},
{
"_id": "03",
"count": 7
},
{
"_id": "04",
"count": 20
}
]
```

lodash create new json object from existing one

I want to delete and rename some props of my existing JSON Object to use it with select2/select2 query plugins
My JSON object that i need to transform is:
[
{
"id": 1,
"type": "Subject1",
"createdAt": "2016-02-19T23:03:12.000Z",
"updatedAt": "2016-02-19T23:03:12.000Z",
"Tags": [
{
"id": 1,
"name": "sub1",
"createdAt": "2016-02-19T23:03:12.000Z",
"updatedAt": "2016-02-19T23:03:12.000Z",
"tagType": 1
}
]
},
{
"id": 2,
"type": "Subject2",
"createdAt": "2016-02-19T23:03:12.000Z",
"updatedAt": "2016-02-19T23:03:12.000Z",
"Tags": [
{
"id": 16,
"name": "sub2",
"createdAt": "2016-02-19T23:03:12.000Z",
"updatedAt": "2016-02-19T23:03:12.000Z",
"tagType": 2
}
]
},
{
"id": 3,
"type": "Subject3",
"createdAt": "2016-02-19T23:03:12.000Z",
"updatedAt": "2016-02-19T23:03:12.000Z",
"Tags": [
{
"id": 22,
"name": "sub3",
"createdAt": "2016-02-19T23:03:12.000Z",
"updatedAt": "2016-02-19T23:03:12.000Z",
"tagType": 3
}
]
}
]
To
[
{
"text": "Subject1",
"children": [
{
"id": 1,
"text": "sub1"
}
]
},
{
"text": "Subject2",
"children": [
{
"id": 16,
"text": "sub2"
}
]
},
{
"text": "Subject3",
"children": [
{
"id": 22,
"text": "sub3"
}
]
}
]
I need to :
rename name and type to text
delete tagType, updatedAt and createdAt
rename Tags to children
remove the id of each top objects
Is there a way to do all this using lodash ?
What the best way?
var res = _.map(items, function(item){
return {
text: item.type,
children: _.map(item.Tags, function(tag){
return {
id: tag.id,
text: tag.name
};
})
};
});
I succed using this link by nesting two return :
Creating new javascript Object form existing one
var result = tags.map(function(obj) {
return {
text: obj.type,
childrens:obj.Tags.map(function(obj) {
return {
id : obj.id,
text : obj.name
}
})
};
});

Categories