Angular: Get parent and specific child from JSON - arrays

I have this object:
elements120: {
"data": {
"name": "120",
"type": "120"
},
"children": [
{
"data": {
"name": "120A",
"type": "120A"
},
"children": []
},
{
"data": {
"name": "120B",
"type": "120B"
},
"children": []
},
{
"data": {
"name": "120C",
"type": "120C"
},
"children": []
}
]
}
I need to make some new Json as these below:
Json 1:
filtered120A{
"data": {
"name": "120",
"type": "120"
},
"children": [
{
"data": {
"name": "120A",
"type": "120A"
},
"children": []
}
]
}
Json 2:
filtered120B{
"data": {
"name": "120",
"type": "120"
},
"children": [
{
"data": {
"name": "120B",
"type": "120B"
},
"children": []
}
]
}
Json 3:
filtered120C{
"data": {
"name": "120",
"type": "120"
},
"children": [
{
"data": {
"name": "120C",
"type": "120C"
},
"children": []
}
]
}
I tried to do this in order to get only the first children node and delete the others (it's the only way it works me). For 120B and 120C i put as first child the value of the node that I needed for each case
this.filtered120A = utils.deepClone(this.elements120);
this.filtered120B = utils.deepClone(this.elements120);
this.filtered120C = utils.deepClone(this.elements120);
this.filtered120A = this.filtered120A.filter((element) => {
delete element.children[1];
delete element.children[2];
return true;
});
this.filtered120B = this.filtered120B.filter((element) => {
element.children[0] = element.children[1];
delete element.children[1];
delete element.children[2];
return true;
});
this.filtered120C = this.filtered120C.filter((element) => {
element.children[0] = element.children[2];
delete element.children[1];
delete element.children[2];
return true;
});
It works, but the code is not very elegant. I would like to know if there is any other better alternative.

Here you go:
function getOutputs(input) {
const outputs = [];
for (const child of input.children) {
outputs.push({
"data": {
"name": input.data.name,
"type": input.data.type
},
"children": [child]
});
}
return outputs;
}
const inputs = {
"data": {
"name": "120",
"type": "120"
},
"children": [
{
"data": {
"name": "120A",
"type": "120A"
},
"children": []
},
{
"data": {
"name": "120B",
"type": "120B"
},
"children": []
},
{
"data": {
"name": "120C",
"type": "120C"
},
"children": []
}
]
};
const outputs = getOutputs(inputs);
console.log(outputs[0]); // output1
console.log(outputs[1]); // output2
console.log(outputs[2]); // output3

Related

Remove object from nested array with recursion

I'm working with vue-draggable for creating a navigation menu. The result array could have N deep levels.
I want to remove an object by it's id.
The array looks like:
[
{
"id": 1,
"name": "Viedma",
"slug": "viedma",
"children": []
},
{
"id": 6,
"name": "Cultura",
"slug": "Cultura",
"children": [
{
"id": 2,
"name": "Rio Negro",
"slug": "rio-negro",
"children": [
{
"id": 4,
"name": "Edictos",
"slug": "edictos",
"children": []
},
{
"id": 5,
"name": "Deportes",
"slug": "deportes",
"children": []
}
]
}
]
},
{
"id": 3,
"name": "Policiales",
"slug": "policiales",
"children": []
}
]
I've tried the solution from remove object from nested array but since I have an array instead of a main object it doesn't work.
Please note that I'm using vue 3 with composition API.
This is what I have so far. The remove() method is called from UI
setup(props, context) {
const resources = ref(props.data)
const removeFromTree = (parent, childNameToRemove) => {
parent.children = parent.children
.filter(function(child){ return child.name !== childNameToRemove})
.map(function(child){ return removeFromTree(child, childNameToRemove)})
return parent
}
const remove = (element) => {
var tree = [...resources.value]
resources.value = removeFromTree(tree, element.name)
}
return {
resources,
remove
}
}
BTW, If parent is removed, all it's children should be removed too.
Your function takes parent as an object but you passing tree as an array. You can do like this
function removeItemByName(items, itemName) {
return items.filter(item => item.name !== itemName)
.map(item => {
item.children = removeItemByName(item.children, itemName)
return item
})
}
const input = [
{
"id": 1,
"name": "Viedma",
"slug": "viedma",
"children": []
},
{
"id": 6,
"name": "Cultura",
"slug": "Cultura",
"children": [
{
"id": 2,
"name": "Rio Negro",
"slug": "rio-negro",
"children": [
{
"id": 4,
"name": "Edictos",
"slug": "edictos",
"children": []
},
{
"id": 5,
"name": "Deportes",
"slug": "deportes",
"children": []
}
]
}
]
},
{
"id": 3,
"name": "Policiales",
"slug": "policiales",
"children": []
}
]
console.log(removeItemByName(input, 'Policiales'))
console.log(removeItemByName(input, 'Deportes'))

how to map and array inside of an object

So here I have an object that I am trying to map:
var bakery = {
"items":
{
"item":[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters": {
"batter":[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
]
},
"topping":[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
...
...
...
]
}
}
This is the target outcome
var target = [{
"id": 1, //as an int
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters": "all of the batter types as a string",
"ingredients": [],//a copy of all the toppings
"countOfFillings": 0
}];
And here is my mapping function
// creates variable bakeryArray that contains the actual Array inside of Baker var
var bakeryArray = bakery.items.item
// newCakes var invoked map function with the bakeryArray
var newCakes = bakeryArray.map(mapCakes)
function mapCakes(oldCakes) {
let batter = oldCakes.batters.batter
console.log(batter, "batter Logged")
var newCakesObject = {
type: oldCakes.type,
name: oldCakes.name,
ppu: oldCakes.ppu,
batters: batter.type,
ingredients: "ingridients",
countOfFillings: "total number of ingrediensts"
};
return newCakesObject;
};
I am running into problems in getting the Batter, Ingredients, and countOfFillings from the old object into the new one.
The only thing I can think of doing in order to get the batters in the newCakesObject is that I have to create another mapping function for the batter (I put my attempt at that below)? and then invoke that in the mapCakes function under batters? but every time I create another function for that I get an error saying that it's undefined once I call newBatterArray in the console
var newBatterArray = bakeryArray.map(mapBatters)
function mapBatters(oldarray) {
let theBatters = oldarray.batters.batter
console.log(theBatters.type, "we ran")
var newBatters = {
type: theBatters.type
}
return newBatters;
}
To have a much more clear interpretation of your bakery object I have tweaked it a bit
var bakery = {
"items":[
{
"id": "0001",
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":[
{ "id": "1001", "type": "Regular" },
{ "id": "1002", "type": "Chocolate" },
{ "id": "1003", "type": "Blueberry" },
{ "id": "1004", "type": "Devil's Food" }
],
"toppings":[
{ "id": "5001", "type": "None" },
{ "id": "5002", "type": "Glazed" },
{ "id": "5005", "type": "Sugar" },
{ "id": "5007", "type": "Powdered Sugar" },
{ "id": "5006", "type": "Chocolate with Sprinkles" },
{ "id": "5003", "type": "Chocolate" },
{ "id": "5004", "type": "Maple" }
]
},
{
"id": "0002",
"type": "donut",
"name": "Cake",
"ppu": 0.65,
"batters":[
{ "id": "1001", "type": "Regular1" },
{ "id": "1002", "type": "Chocolate1" },
{ "id": "1003", "type": "Blueberry1" },
{ "id": "1004", "type": "Devil's Food1" }
],
"toppings":[
{ "id": "5001", "type": "None1" },
{ "id": "5002", "type": "Glazed1" },
{ "id": "5005", "type": "Sugar1" },
{ "id": "5007", "type": "Powdered Sugar1" },
{ "id": "5006", "type": "Chocolate with Sprinkles1" },
{ "id": "5003", "type": "Chocolate1" },
{ "id": "5004", "type": "Maple1" }
]
},
...
...
...
...
]
}
Now You can iterate through each item and build your target array as follows
var target = [];
// define reducer function for each item in bakery.items
const reduceToTarget = item => {
var obj = {};
obj.id = item.id;
obj.type = item.type;
obj.name = item.name;
obj.ppu = item.ppu;
obj.batters = '';
item.batters.forEach(b => obj.batters+=b.type+'|');
obj.ingredients = item.toppings;
target.push(obj);
}
// Now you can call the reduceToTarget function to get the desired target list/array
bakery.items.forEach(reduceToTarget);
The output for this looks something like this
target = [
{
id: "0001"
type: "donut"
name: "Cake"
ppu: 0.55
batters: "Regular|Chocolate|Blueberry|Devil's Food|",
ingredients : [/* list of ingredients*/]
},
{
id: "0002"
type: "donut"
name: "Cake"
ppu: 0.65
batters: "Regular|Chocolate|Blueberry|Devil's Food|",
ingredients : [/* list of ingredients*/]
}
]
NOTE:
For getting the countOfFillings you can simply call length() function on your ingredients list for any element in target

DataTables - Load data from pre-defined JSON

I have a problem pointing dataTable to the right spot in the JSON. I receive a nested array:
{
"status": "ok",
"count": "7",
"msg ": "Operation Successful",
"data": [{
"contactHasServiceArea": true,
"issueCategories": [{
"id": "8",
"description": "Finance"
},
{
"id": "9",
"description": "Housing"
},
{
"id": "10",
"description": "International"
}
],
"cases": [{
"id": 31645,
"client_name": "Matthew",
"issue": "Assessment Completion",
"referral": null,
"opened_date": "10\/07\/2017",
"case_status": "Open"
}, {
"id": 31668,
"client_name": "Fanky ",
"issue": "Complex",
"referral": null,
"opened_date": "01\/07\/2017",
"case_status": "Open"
}]
}]
}
How do I point to the "cases" object? I'm sure this is simply, but I'm confused by the many options in the dataTables config.
I tried variations of data, dataSrc as well as data.cases or just cases, etc.
Thanks
$('#cases_table').DataTable( {
"ajax": "ajax/getCases",
"dataSrc" : "data.cases",
"data" : "cases",
"columns": [
{ "data": "client_name" },
{ "data": "issue" },
{ "data": "referral" },
{ "data": "opened_date" },
{ "data": "case_status" }
]
} );
You can configure like this:
$('#cases_table').DataTable( {
"ajax": {
"url": "ajax/getCases",
"dataSrc" : "data.cases"
},
"columns": [
{ "data": "client_name" },
{ "data": "issue" },
{ "data": "referral" },
{ "data": "opened_date" },
{ "data": "case_status" }
]
} );
datasrc points into the returns json. Remove the data option.

ElasticSearch-Kibana : filter array by key

I have data with one parameter which is an array. I know that objects in array are not well supported in Kibana, however I would like to know if there is a way to filter that array with only one value for the key. I mean :
This is a json for exemple :
{
"_index": "index",
"_type": "data",
"_id": "8",
"_version": 2,
"_score": 1,
"_source": {
"envelope": {
"version": "0.0.1",
"submitter": "VF12RBU1D53087510",
"MetaData": {
"SpecificMetaData": [
{
"key": "key1",
"value": "94"
},
{
"key": "key2",
"value": "0"
}
]
}
}
}
}
And I would like to only have the data which contains key1 in my SpecificMetaData array in order to plot them. For now, when I plot SpecificMetaData.value it takes all the values of the array (value of key1 and key2) and doesn't propose SpecificMetaData.value1 and SpecificMetaData.value2.
If you need more information, tell me. Thank you.
you may need to map your data to mappings so as SpecificMetaData should act as nested_type and inner_hits of nested filter can supply you with objects which have key1.
PUT envelope_index
{
"mappings": {
"document_type": {
"properties": {
"envelope": {
"type": "object",
"properties": {
"version": {
"type": "text"
},
"submitter": {
"type": "text"
},
"MetaData": {
"type": "object",
"properties": {
"SpecificMetaData": {
"type": "nested"
}
}
}
}
}
}
}
}
}
POST envelope_index/document_type
{
"envelope": {
"version": "0.0.1",
"submitter": "VF12RBU1D53087510",
"MetaData": {
"SpecificMetaData": [{
"key": "key1",
"value": "94"
},
{
"key": "key2",
"value": "0"
}
]
}
}
}
POST envelope_index/_search
{
"query": {
"bool": {
"must": [
{
"nested": {
"inner_hits": {},
"path": "envelope.MetaData.SpecificMetaData",
"query": {
"bool": {
"must": [
{
"term": {
"envelope.MetaData.SpecificMetaData.key": {
"value": "key1"
}
}
}
]
}
}
}
}
]
}
}
}

Underscore js to retrieve data from array

I'm assigned a task to get data using underscore js.
This is my JSON :
$scope.myData= {
"buslist":
{
"code":"1",
"message":"Success",
"fromStationCode":"71",
"searchResult": [
{
"arrivalTime": "17:00:00",
"availableSeats": "42",
"boardingPointDetails": [
{
"code": "1631",
"name": "Koyambedu",
"time": "09:30:00"
},
{
"code": "961296",
"name": "Nerkundram",
"time": "09:45:00"
}
]
},
{
"arrivalTime": "18:00:00",
"availableSeats": "32",
"boardingPointDetails": [
{
"code": "2084",
"name": "Adyar",
"time": "09:30:00"
},
{
"code": "961296",
"name": "Madurai",
"time": "09:45:00"
}
]
}
]
}
}
From this I want only "name" field. By doing this :
$scope.bdata = _.pluck($scope.myTest.buslist.searchResult, 'boardingPointDetails');
I got all "boardingPointDetails". The result looks like:
[ [
{
"code": "2084",
"name": "Adyar",
"time": "09:30:00"
},
{
"code": "961296",
"name": "Madurai",
"time": "09:45:00"
}
],[
{
"code": "1631",
"name": "Koyambedu",
"time": "09:30:00"
},
{
"code": "961296",
"name": "Nerkundram",
"time": "09:45:00"
}
],[
{
...
}
]
...
]
Help me to retrieve only "name" from this.
If you just want array of names like ['Koyambedu', 'Madurai'] then below code would work.
$scope.bdata = _.pluck($scope.myTest.buslist.searchResult, 'boardingPointDetails');
// Flatten the data.
$scope.flatbdata = _.flatten($scope.bdata, true);
$scope.flatbdata = $scope.flatbdata.filter(function(d){
return d != undefined && d.hasOwnProperty('name')
})
// map calls a provided callback function once for each element in an array, in order, and constructs a new array from the results
$scope.names = $scope.flatbdata.map(function(d){
return d.name;
});
Refer below links :
http://underscorejs.org/#flatten
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
If you just want the array of names, here it is:
$scope.bdata = _.pluck($scope.myTest.buslist.searchResult, 'boardingPointDetails');
var res= _.flatten($scope.bdata);
res=_.pluck(res,'name');
console.log(res);
var temp = _.pluck(_.flatten($scope.bdata),'name')
temp will have ["Koyambedu", "Nerkundram", "Adyar", "Madurai"]
Try this.
$scope = {}; // in real project you don't need this. it's just for snippet.
$scope.myData = {
"buslist": {
"code": "1",
"message": "Success",
"fromStationCode": "71",
"searchResult": [{
"arrivalTime": "17:00:00",
"availableSeats": "42",
"boardingPointDetails": [{
"code": "1631",
"name": "Koyambedu",
"time": "09:30:00"
}, {
"code": "961296",
"name": "Nerkundram",
"time": "09:45:00"
}]
}, {
"arrivalTime": "18:00:00",
"availableSeats": "32",
"boardingPointDetails": [{
"code": "2084",
"name": "Adyar",
"time": "09:30:00"
}, {
"code": "961296",
"name": "Madurai",
"time": "09:45:00"
}]
}]
}
};
$scope.names = _.chain($scope.myData.buslist.searchResult).pluck("boardingPointDetails").flatten(true).map(function(item) {
return item.name;
}).value();
console.log($scope.names);
<script src="http://underscorejs.ru/underscore-min.js"></script>

Resources