How to find the value nested inside an array of objects - javascript

Here I have to get value of file_info, I tried doing it using array.includes and array.find(), but got undefined.
My confusion here is related to, under 'facts', the first value is "==", then it has array of values associated to it. I could not figure out to find the values inside that nested object.
I even tried array.find(facts).contains(fileinfo) that did not work as well.
How can I solve this ??
"data": [
{
"task-id": "126e7267",
"type": "A",
"output": {...}
},
{
"task-id": "bdfddff3",
"type": "B",
"output": {
"id": "12b54370",
"facts": [
{
"==": [
"A",
{
"#type": "AA",
"#value": {
"id": "12b54370-4594-4033-a299-5480b593ee6d",
"facts": [
{
"==": [
"time",
1575759643.904254
]
},
{
"==": [
"mime",
"text/plain"
]
},
{
"==": [
"owner",
1000
]
},
{
"==": [
"size",
100
]
},
{
"==": [
"file_info",
"a0s5b2e6e739" // have to find and return this value
]
},
{
"==": [
"time",
{
"#value": "2019-12-07T23:01:50.703Z",
"#type": "timestamp"
}
]
},
],
}
}
]
},
....
]
}
},
{
"task-id": "5f557eac",
"type": "C",
....
},
],

I have tried to validate your json string. It seems to be invalid. For answering this question , i would assume below string to be your json :
{"data":[{"task-id":"126e7267","type":"A","output":{}},{"task-id":"bdfddff3","type":"B","output":{"id":"12b54370","facts":[{"==":["A",{"#type":"AA","#value":{"id":"12b54370-4594-4033-a299-5480b593ee6d","facts":[{"==":[{"time":{"#value":"1575759643.904254"}}]},{"==":["mime","text/plain"]},{"==":["owner",1000]},{"==":["size",100]},{"==":[{"file_info":"a0s5b2e6e739"}]},{"==":["time",{"#value":"2019-12-07T23:01:50.703Z","#type":"timestamp"}]}]}}]}]}},{"task-id":"5f557eac","type":"C"}]}
I had tried to figure out a repetative pattern in your json but since "#value" tag is seen inside only one "facts" object below code should help you getting started . For given json , below code prints the value of "file_info"(Here , i'am assuming that "file_info" should be followed by a colon(:) i.e. "a0s5b2e6e739" is the value you are looking for) :
var jsonStr = '{"data":[{"task-id":"126e7267","type":"A","output":{}},{"task-id":"bdfddff3","type":"B","output":{"id":"12b54370","facts":[{"==":["A",{"#type":"AA","#value":{"id":"12b54370-4594-4033-a299-5480b593ee6d","facts":[{"==":[{"time":{"#value":"1575759643.904254"}}]},{"==":["mime","text/plain"]},{"==":["owner",1000]},{"==":["size",100]},{"==":[{"file_info":"a0s5b2e6e739"}]},{"==":["time",{"#value":"2019-12-07T23:01:50.703Z","#type":"timestamp"}]}]}}]}]}},{"task-id":"5f557eac","type":"C"}]}';
var jsonObj = JSON.parse(jsonStr);
//If there is a repetative pattern , you can replace this hard coding with your pattern.
var objArray = jsonObj["data"][1]["output"]["facts"][0]["=="][1]["#value"]["facts"];
console.log(objArray);
if(objArray && objArray.length >0){
for(let i =0;i<objArray.length;i++){
if(objArray[i] && objArray[i]["=="] && objArray[i]["=="].length > 0 && objArray[i]["=="][0]["file_info"]){
//here "file_info" is fetched
console.log('here ',objArray[i]["=="][0]["file_info"]);
}
}
}
Hope above code helps you to get started.

You can map and filter the object/array to get the result if the format is fixed. Here, I am writing to a Map and retrieving the property I need at the very end.
let data = [
{
"task-id": "126e7267",
"type": "A",
"output": {}
},
{
"task-id": "bdfddff3",
"type": "B",
"output": {
"id": "12b54370",
"facts": [
{
"==": [
"A",
{
"#type": "AA",
"#value": {
"id": "12b54370-4594-4033-a299-5480b593ee6d",
"facts": [
{
"==": [
"time",
1575759643.904254
]
},
{
"==": [
"mime",
"text/plain"
]
},
{
"==": [
"owner",
1000
]
},
{
"==": [
"size",
100
]
},
{
"==": [
"file_info",
"a0s5b2e6e739" // have to find and return this value
]
},
{
"==": [
"time",
{
"#value": "2019-12-07T23:01:50.703Z",
"#type": "timestamp"
}
]
},
],
}
}
]
}
]
}
},
{
"task-id": "5f557eac",
"type": "C",
"output": {}
}
]
const map = new Map()
const facts = data
.map(d => d.output)
.filter(o => o.hasOwnProperty('facts'))
.map(d => d.facts)
.map(i => i[0]["=="][1])
.map(d => d["#value"].facts)
const item = facts.forEach(o => o.forEach(i => map.set(i["=="][0], i["=="][1])))
console.log(map.get("file_info"))

Related

Javascript : How to remove object Item from nested Object Array? [duplicate]

This question already has answers here:
Filtering array of objects with arrays based on nested value
(8 answers)
Closed last month.
I need to remove one item from nested object array by filtering key value
sample json
[
{
"featureID": "e0152c71-657f-4bc2-b7f5-77e4d5a2a5a0",
"feature": "TestTwo",
"type": "TestTwo",
"rules": [
{
"ruleId": "89919182-feb1-402c-b9ad-03ae62586f84",
"ruleName": "Machine Guarding",
"featureName": "TestTwo",
"parameters": [
]
},
{
"ruleId": "e5361f7f-d8ae-424d-b781-a01987111181",
"ruleName": "Eye&Face Protection",
"featureName": "TestTwo",
"parameters": [
]
},
]
},
{
"featureID": "67d6e1bf-3919-4dcc-b636-236ab41d431b",
"feature": "TestThree",
"type": "TestThree",
"rules": [
{
"ruleId": "4e00e08e-6a34-47cf-9012-0800bc0063f2",
"ruleName": "Maximum People",
"featureName": "TestThree",
"parameters": [
]
},
{
"ruleId": "a9ab3ce2-e69c-4c0c-b561-1107baed1e68",
"ruleName": "Redzone",
"featureName": "TestThree",
"parameters": [
]
}
]
},
]
In above JSON, I need to remove an item from "rules" array by "ruleId" property.
i.e : remove "ruleName":"Machine Guarding" item by that ruleId property.
I tried below
deleteItems(argId){
this.done.find((items,d)=>items.feature == argID.featureName).rules.filter((int,ind)=>int.ruleId == argID.ruleId)
}
The above function passes the respective "ruleId" property.
const data=[{featureID:"e0152c71-657f-4bc2-b7f5-77e4d5a2a5a0",feature:"TestTwo",type:"TestTwo",rules:[{ruleId:"89919182-feb1-402c-b9ad-03ae62586f84",ruleName:"Machine Guarding",featureName:"TestTwo",parameters:[]},{ruleId:"e5361f7f-d8ae-424d-b781-a01987111181",ruleName:"Eye&Face Protection",featureName:"TestTwo",parameters:[]}]},{featureID:"67d6e1bf-3919-4dcc-b636-236ab41d431b",feature:"TestThree",type:"TestThree",rules:[{ruleId:"4e00e08e-6a34-47cf-9012-0800bc0063f2",ruleName:"Maximum People",featureName:"TestThree",parameters:[]},{ruleId:"a9ab3ce2-e69c-4c0c-b561-1107baed1e68",ruleName:"Redzone",featureName:"TestThree",parameters:[]}]}];
const deleteItems = (ruleIdToFilter) => {
return data.map((item) => {
item.rules = item.rules.filter((rule) => ruleIdToFilter != rule.ruleId);
return item;
});
};
let response = deleteItems("89919182-feb1-402c-b9ad-03ae62586f84");
console.log(response);

filter an array of object based on a key and get only key value

I want to filter an array of objects based on a key selected. If any of the object has selected: true, I want its ID in return. For e.g. below:
Below is the array I have:
arr = [
{
"_id": "6311eb86cc42295428bb663a",
"name": "Southeast Asia",
"language": [
"English"
],
"selected": true
},
{
"_id": "6311eb86cc42295428bb663f",
"name": "USA",
"language": [
"English"
],
},
{
"_id": "6311eb86cc42295428bb6635",
"name": "MENA",
"language": [
"English"
],
"selected": true
}
]
Logic used to get an _id from it:
arr.filter(item => {
if(item.selected) {
retrun item._id;
}
});
Expected output:
[{
_id: '6311eb86cc42295428bb663a'
}, {
_id: '6311eb86cc42295428bb6635'
}]
But I got the whole array of object in return instead of just _id.
How can I work around this to get only _id?
The array.filter method only filters the input array without changing it's content. The callback you're passing in your code is only expected to return true or false. To reshape your result you need to use filter along with array.map
const arr = [
{
"_id": "6311eb86cc42295428bb663a",
"name": "Southeast Asia",
"language": [
"English"
],
"selected": true
},
{
"_id": "6311eb86cc42295428bb663f",
"name": "USA",
"language": [
"English"
],
},
{
"_id": "6311eb86cc42295428bb6635",
"name": "MENA",
"language": [
"English"
],
"selected": true
}
];
const result = arr.filter(item => item.selected).map(item => ({_id: item._id}));
console.log(result);
const data = arr = [
{
"_id": "6311eb86cc42295428bb663a",
"name": "Southeast Asia",
"language": [
"English"
],
"selected": true
},
{
"_id": "6311eb86cc42295428bb663f",
"name": "USA",
"language": [
"English"
],
},
{
"_id": "6311eb86cc42295428bb6635",
"name": "MENA",
"language": [
"English"
],
"selected": true
}
]
let result = data.filter(d => d.selected).map(d => {
let obj ={}
obj['_id'] = d._id
return obj
})
console.log(result)
Array.filter returns an array based on your function.
So you have to save that variable like this:
let arr2= arr.filter(element => {
if(element.selected == true)
return (element)
});
You need to use both filtered and map functions
const filteredArr = arr.filter((element)=>{
return element.selected != null
})
const reducedArr = filteredArr.map((element) => {
return {_id:element._id}
})
You can use map as below :
let filtered = arr.filter(item => { if(item.selected) { return item._id;}}).map(item => ({_id: item._id}));;
expected output :
[ { _id: '6311eb86cc42295428bb663a'}, { _id: '6311eb86cc42295428bb6635'}]
filter + map == reduce
so this will give you your output:
arr.reduce((acc,val)=>{
if(val.selected){
acc.push({_id: val._id})
}
return acc
},[])
Or, most likely you actually need just array of values:
arr.reduce((acc,val)=>{
if(val.selected){
acc.push(val._id)
}
return acc
},[])

Put JSON data inside another object of the same JSON

I need to put the images that are on "included" into "data:{relationships: { field_imagen: { data" but the problem is that i just managed to put only the first image into every index using map and find
noticiasImages.forEach(function(data: { relationships: { field_imagen: {data: {id:any}}}} ) {
var nestedArray = noticiasData.map((noticiasImages: { id: any; }) => noticiasImages == noticiasData);
data = nestedArray && noticiasImages || noticiasData;
});
And this is my json (example node)
{
"data": [
"relationships": {
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
}
],
}
]
},
this is the included object, who is in the same level as data
"included": [
"attributes": {
"drupal_internal__fid": 8798,
"langcode": "es",
"filename": "_DSC6472 - copia.jpg",
"uri": {
"value": "public:\/\/2019-11\/_DSC6472 - copia.jpg",
"url": "\/sites\/default\/files\/2019-11\/_DSC6472%20-%20copia.jpg"
},
},
,
Expected Result:
"data": [
"relationships": {
"type": "node--actualidad_institucional",
"id": "71514647-af49-4136-8a28-9563d133070a",
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
"uri": {
"value": "public:\/\/2019-11\/_DSC6472 - copia.jpg",
"url": "\/sites\/default\/files\/2019-11\/_DSC6472%20-%20copia.jpg"
},
}
}
},
I put the uri from included into field_imagen. Tried to resolve like that, but it just put only the first image of the Array from the included object in every node:
showNoticias() {
this.frontService.getNoticias()
.subscribe((data: Noticias) => {
this.noticiasImages = Array.from(data.included);
this.noticiasData = Array.from(data.data);
let noticiasImages = this.noticiasImages.map((data: {id: any}) => data.id);
let noticiasData = this.noticiasData.map((data:{relationships: { field_imagen: { data: { id: any; }}}}) => data.relationships.field_imagen.data.id);
noticiasImages.forEach(function(data: { relationships: { field_imagen: {data: {id:any}}}} ) {
var nestedArray = noticiasData.map((noticiasImages: { id: any; }) => noticiasImages == noticiasData);
data = nestedArray && noticiasImages || noticiasData;
});
console.log(data);
});
}
Hope you can help me, thanks!
UPDATE: tried that but didnt work like expected
let merged = data.data.map((data:{relationships: { field_imagen: { data: any }}}) => Object.assign({}, noticiasImages));
console.log(data)
console.log(merged)
Sometimes using regular for loops are a better option. Using map with objects that have that many properties can get confusing. And using forEach will not give you access to the i index of the iteration in the loop, which makes things easier in this case.
for (let i = 0; i < obj.included.length; i++) {
let uri = obj.included[i].attributes.uri;
obj.data[i].relationships.field_imagen.data[0] = {
...obj.data[i].relationships.field_imagen.data[0],
...uri
}
}
console.log(obj)
Output:
{
"data": [
{
"relationships": {
"field_imagen": {
"data": [
{
"type": "file--file",
"id": "dba917f0-b80f-45ed-a569-69f2ba2b482d",
"value": "public://2019-11/_DSC6472 - copia.jpg",
"url": "/sites/default/files/2019-11/_DSC6472%20-%20copia.jpg"
}
]
}
}
}
],
"included": [
{
"attributes": {
"drupal_internal__fid": 8798,
"langcode": "es",
"filename": "_DSC6472 - copia.jpg",
"uri": {
"value": "public://2019-11/_DSC6472 - copia.jpg",
"url": "/sites/default/files/2019-11/_DSC6472%20-%20copia.jpg"
}
}
}
]
}

How to dynamically build a data structure in pure JavaScript?

Is there any plugin that allow to dynamically build following data structure in plain JavaScript object or JSON?
This is the structure I would like to implement:
Check my plunker (https://plnkr.co/edit/1eWjXLPumuOMhv8BjaNw?p=preview)
{
"name": "Select0",
"id": "select0",
"values": [
"Option1",
"Option2"
],
"dependent": {
"name": "Select1",
"id": "select1",
"values": {
"Option1": [
"Option11",
"Option12"
],
"Option2": [
"Option21",
"Option22"
]
},
"dependent": {
"name": "Select2",
"id": "select2",
"values": {
"Option1": {
"Option11": [
"Option111",
"Option112"
],
"Option12": [
"Option121",
"Option122"
]
},
"Option2": {
"Option21": [
"Option211",
"Option212"
],
"Option22": [
"Option221",
"Option222"
]
}
},
"dependent": []
}
}
}
Note that you can set values on properties on an object and then print it as a JSON.
var obj = {};
object.name = "Select0";
// Set more properities.
// Stringify object to JSON format looking as the one in the question.
var json = JSON.stringify(obj, null, 2);
// Verify by printing on the screen.
console.log(json);

How to convert object into array with lodash

I have below object
{
"holdings": [
{
"label": "International",
"value": 6
},
{
"label": "Federal",
"value": 4
},
{
"label": "Provincial",
"value": 7
}
]
}
I want to convert it into below object with lodash
{
"holdings": [
[
"International",
6
],
[
"Federal",
4
],
[
"Provincial",
7
],
[
"Corporate",
7
]
]
}
is there any way to change it. Please suggest.
If you want to use only lodash, then you can do it with _.mapValues and _.values to get the result, like this
console.log(_.mapValues(data, _.partial(_.map, _, _.values)));
// { holdings: [ [ 'International', 6 ], [ 'Federal', 4 ], [ 'Provincial', 7 ] ] }
The same can be written without the partial function, like this
console.log(_.mapValues(data, function(currentArray) {
return _.map(currentArray, _.values)
}));
// { holdings: [ [ 'International', 6 ], [ 'Federal', 4 ], [ 'Provincial', 7 ] ] }
This works recursively (So has to be called on the holdings property if you want to keep that) and "understands" nested objects and nested arrays. (vanilla JS):
var source = {
"holdings": [
{
"label": "International",
"value": 6
},
{
"label": "Federal",
"value": 4
},
{
"label": "Provincial",
"value": 7
}
]
}
function ObjToArray(obj) {
var arr = obj instanceof Array;
return (arr ? obj : Object.keys(obj)).map(function(i) {
var val = arr ? i : obj[i];
if(typeof val === 'object')
return ObjToArray(val);
else
return val;
});
}
alert(JSON.stringify(ObjToArray(source.holdings, ' ')));

Categories