I want to get Hierarchy from an Array - Angular 8 - arrays

I have an Array and One String Value. I want to get the Hierarchy of the String into an Array.
For example, I have a string value "Casuals". "Casuals" value is inside the "Shirts" object. "Shirts" value is inside the "Men" object. And "Men" value is inside the "Default Category" object. So, this is how the logic should be work.
Here is my Sample Array:
{
"id": 2,
"name": "Default Category",
"children_data": [
{
"id": 3,
"name": "Men",
"children_data": [
{
"id": 11,
"name": "T-Shirts",
"children_data": [
{
"id": 27,
"name": "Polos"
},
{
"id": 28,
"name": "Tees"
}
]
},
{
"id": 12,
"name": "Shirts",
"children_data": [
{
"id": 30,
"name": "Casuals"
},
{
"id": 31,
"name": "Formals"
}
]
}
]
},
{
"id": 4,
"name": "Women",
"children_data": [
{
"id": 80,
"name": "Western wears",
"children_data": [
{
"id": 81,
"name": "T-Shirts"
},
{
"id": 82,
"name": "Tank & Crop Tops"
}
]
},
{
"id": 21,
"name": "Ethnic wears",
"children_data": [
{
"id": 51,
"name": "Kurta & Kurtis"
},
{
"id": 52,
"name": "Kurta Sets"
}
]
}
]
}
]
}
And I have the value
let myCategory = "Casuals";
So, that I want to get my final value is ["Default Category", "Men", "Shirts", "Casuals"]
I'm still struggling to get the Hierarchy of the value.

Please try below code for your problem. Let me know If you are facing any issue. Please see working demo.
Call getFilterdObject(data,'Polos'), data is your object.
function getFilterdObject(obj,param){
let finalArray =[];
finalArray.push(obj.name);
if(obj['name'] != param && obj['children_data']){
let filterData = obj['children_data'].filter(function search(a) {
var children;
if (a.name === param) {
return true;
}
if (!Array.isArray(a.children_data)) {
return false;
}
children = a.children_data.filter(search);
if (children.length) {
a.children_data = children;
return true;
}
});
if(filterData.length){
getArray(filterData, param);
}
else{
finalArray =[];
}
}
function getArray(obj,param){
if(obj.length){
obj.map((val)=>{
finalArray.push(val.name);
if(val.children_data && val.name != param){
getArray(val.children_data, param);
}
});
}
}
return finalArray;
};

It is necessary to use Depth First Search Algorithm to recursively search a higher object and then use recursive approach to find all parents:
// Depth First Search Algorithm
function getParentNodeByChild(obj, nameToFind) {
if (obj.children_data) {
if (obj.children_data.some(ch => ch.name == nameToFind))
return obj;
else {
for (let item of obj.children_data) {
if (item.children_data) {
let check = this.getParentNodeByChild(item, nameToFind)
if (check) {
return check;
}
}
}
}
}
return null
}
function getParentObject(nameToFind) {
let parentObj;
if (obj.children_data && obj.children_data.some(ch => ch.name == nameToFind))
return obj;
else {
for (let i = 0; i < obj.children_data.length; ++i) {
parentObj = getParentNodeByChild(obj.children_data[i], nameToFind);
if (parentObj)
break;
}
return parentObj;
}
}
const getAllNames = keyName => {
const parentObject = getParentObject(keyName);
if (parentObject != null && parentObject.name != null) {
names.push(parentObject.name)
getAllNames(parentObject.name);
}
}
let names = [];
let keyToFind = 'Casuals';
getAllNames(keyToFind);
names.push(keyToFind);
console.log(`names`, names);
An example:
let obj = {
"id": 2,
"name": "Default Category",
"children_data": [
{
"id": 3,
"name": "Men",
"children_data": [
{
"id": 11,
"name": "T-Shirts",
"children_data": [
{
"id": 27,
"name": "Polos"
},
{
"id": 28,
"name": "Tees"
}
]
},
{
"id": 12,
"name": "Shirts",
"children_data": [
{
"id": 30,
"name": "Casuals"
},
{
"id": 31,
"name": "Formals"
}
]
}
]
},
{
"id": 4,
"name": "Women",
"children_data": [
{
"id": 80,
"name": "Western wears",
"children_data": [
{
"id": 81,
"name": "T-Shirts"
},
{
"id": 82,
"name": "Tank & Crop Tops"
}
]
},
{
"id": 21,
"name": "Ethnic wears",
"children_data": [
{
"id": 51,
"name": "Kurta & Kurtis"
},
{
"id": 52,
"name": "Kurta Sets"
}
]
}
]
}
]
};
// Depth First Search Algorithm
function getParentNodeByChild(obj, nameToFind) {
if (obj.children_data) {
if (obj.children_data.some(ch => ch.name == nameToFind))
return obj;
else {
for (let item of obj.children_data) {
if (item.children_data) {
let check = this.getParentNodeByChild(item, nameToFind)
if (check) {
return check;
}
}
}
}
}
return null
}
function getParentObject(nameToFind) {
let parentObj;
if (obj.children_data && obj.children_data.some(ch => ch.name == nameToFind))
return obj;
else {
for (let i = 0; i < obj.children_data.length; ++i) {
parentObj = getParentNodeByChild(obj.children_data[i], nameToFind);
if (parentObj)
break;
}
return parentObj;
}
}
const getAllNames = keyName => {
const parentObject = getParentObject(keyName);
if (parentObject != null && parentObject.name != null) {
names.push(parentObject.name)
getAllNames(parentObject.name);
}
}
let names = [];
let keyToFind = 'Casuals';
getAllNames(keyToFind);
names.push(keyToFind);
console.log(`names`, names);

Related

Json flattening in Snowflake - array, data object

Fairly new to this but can someone help me?
I have the following JSON:
{
"city": [
{
"city_description": {
"text": {
"st": "capital"
}
},
"city_land": {
"st": {
"st": "Other"
}
},
"city_size": {
"id": [
{
"id": "small"
},
{
"id": "big"
},
{
"id": "moderate"
}
]
},
"city_type": {
"id": [
{
"id": "1"
},
{
"id": "2"
},
{
"id": "3"
}
]
},
"conception_date": {
"st": {
"st": "13051977"
}
},
"mark_row": {
"id": {
"id": "1"
}
}
},
{
"city_description": {
"text": {
"st": "cottage"
}
},
"city_land": {
"st": {
"st": "Other"
}
},
"city_size": {
"id": [
{
"id": "small"
},
{
"id": "big"
},
{
"id": "moderate"
}
]
},
"city_type": {
"id": [
{
"id": "1"
},
{
"id": "2"
},
{
"id": "3"
}
]
},
"conception_date": {
"st": {
"st": "15071999"
}
},
"mark_row": {
"id": {
"id": "2"
}
}
}
],
"country": {
"country_code": {
"coordinates": {
"id": "00111022"
},
"name_of_country": {
"st": "Belarus"
},
"desc": {
"st": "Non-eu"
}
},
"country_identifier": {
"id": {
"id": "99"
}
},
"country_description": {
"st": {
"st": "TBD"
}
},
"country_type": {
"is": [
{
"is": "01"
},
{
"is": "X90"
}
]
},
"country_id": {
"si": {
"si": "3"
}
}
}
}
This is stored in snowflake as a string.
I am able to select the data (eg. first column) for the first array.
I am able to select the data (eg. first column) for the first array:
SELECT
f.VALUE:city_description:text:st AS city_description
FROM tableinsnowflake t,
LATERAL flatten(input => t.PARSED_DATA, path => 'city') f
I want to do the same for COUNTRY but seem somehow stuck. Any thoughts? Thanks!
The country could be accessed directly from parsed_data column without using FLATTEN:
SELECT
f.VALUE:city_description:text:st::TEXT AS city_description,
t.parsed_data:country:country_code:name_of_country:st::TEXT AS name_of_country
FROM tab t,
LATERAL FLATTEN(input => t.PARSED_DATA, path => 'city') f

How to extract value from an object and also an array to form another array?

How do I extract "category" from data and use it as the key for the new output array that includes "name" field from listData array
const data = {
"32": {
"id": 32,
"category": "Grocery Items",
}, I
"33": {
"id": 33,
"category": "Household Items",
},
}
This is the listData array and I would need to extract the data from list.
const listData = [
{
"data": {
"list": [
{
"id": 1,
"category_id": 32,
"title": "Eggs",
"category": "Grocery Items"
},
{
"id": 2,
"category_id": 32,
"title": "Bacon",
"category": "Grocery Items"
}
]
}
}
]
Sample Output:
It contains the category from data as the key and data from list array.
const output = {
"Grocery Items": [
{
"id": 1,
"category": "Grocery Items",
"name": "Eggs",
},
{
"id": 2,
"category": "Grocery Items",
"name": "Bacon",
},
]
}
I tried this but did not give the correct structure
const output = Object.values(data).map((acc, { title, id }) => {
let filteredList = [];
listData.forEach((element) => {
console.log(element.data.list)
filteredList = element.data.list
.filter((item) => item.title === title)
});
if (filteredList.length) {
acc[title] = filteredList;
}
return acc;
}, {});
It is possible to use reduce method. Ad mdn says:
The reduce() method executes a user-supplied "reducer" callback
function on each element of the array, in order, passing in the return
value from the calculation on the preceding element. The final result
of running the reducer across all elements of the array is a single
value.
So code would look like this:
let obj = array.reduce((acc, cur) => {
acc[cur.category_id] = {id: cur.category_id, category: cur.category };
return acc;
}, {});
An example can be seen here:
const array = [
{
"id": 1,
"category_id": 32,
"title": "Eggs",
"category": "Grocery Items"
},
{
"id": 2,
"category_id": 33,
"title": "Bacon",
"category": "Grocery Items 33"
}
]
let obj = array.reduce((acc, cur) => {
acc[cur.category_id] = {id: cur.category_id, category: cur.category };
return acc;
}, {});
console.log(obj)

Array : Replace part of array object with other array object

I have an array :
{
"count": 8,
"id": "accountId",
"name": " Account Id",
"values": [
{
"count": 2,
"id": "1234456789000",
"name": "1234456789000"
},
{
"count": 1,
"id": "135792468045",
"name": "135792468045"
},
{
"count": 1,
"id": "309983110022",
"name": "309983110022"
},
{
"count": 2,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 1,
"id": "6ee26149-a156-4665-bd26-a6e46b49a70f",
"name": "6ee26149-a156-4665-bd26-a6e46b49a70f"
},
{
"count": 1,
"id": "927b48ce-efe4-4c20-98f0-ec6c54f59b45",
"name": "927b48ce-efe4-4c20-98f0-ec6c54f59b45"
}
]
}
And I have a 2nd array :
[
{
"count": 2,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 2,
"id": "1234456789000",
"name": "1234456789000"
}
]
The second array, I have filtered based on some requirement.
I want to replace the values from 1st array with second array.
Using typescript code.
Please help here.
If I understand question, you just need iterate by values array and find same id from second array.
function findAndSwitch(object1, array1): void {
object1.values = object1.values.map(el => {
const objToSwitch = array1.find(eleArr => eleArr.id === el.id);
if (objToSwitch) {
return el = objToSwitch;
} else {
return el;
}
});
}
https://stackblitz.com/edit/typescript-dvty4p
Let's say your variable names are obj1 and arr2, respectively. First transform arr2 into an object obj2:
let obj2 = arr2.reduce((acc,cur) => ({...acc,[cur.id]:cur}),{});
Which now looks like this:
{
'432112426686': {
count: 20,
id: '432112426686',
name: '432112426686'
},
'1234456789000': {
count: 20,
id: '1234456789000',
name: '1234456789000'
}
}
Then transform obj1 based on obj2 as follows:
obj1.values = obj1.values.map(value => obj2[value.id] || value);
Please note that since the data in arr2 is identical to the corresponding data in obj1, I have altered the values of count property in arr2 in order to demonstrate that obj1 will be updated accordingly.
DEMO ONE
let obj1 = {
"count": 8,
"id": "accountId",
"name": " Account Id",
"values": [
{
"count": 2,
"id": "1234456789000",
"name": "1234456789000"
},
{
"count": 1,
"id": "135792468045",
"name": "135792468045"
},
{
"count": 1,
"id": "309983110022",
"name": "309983110022"
},
{
"count": 2,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 1,
"id": "6ee26149-a156-4665-bd26-a6e46b49a70f",
"name": "6ee26149-a156-4665-bd26-a6e46b49a70f"
},
{
"count": 1,
"id": "927b48ce-efe4-4c20-98f0-ec6c54f59b45",
"name": "927b48ce-efe4-4c20-98f0-ec6c54f59b45"
}
]
};
let arr2 = [
{
"count": 20,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 20,
"id": "1234456789000",
"name": "1234456789000"
}
];
let obj2 = arr2.reduce((acc,cur) => ({...acc,[cur.id]:cur}),{});
obj1.values = obj1.values.map(value => obj2[value.id] || value);
console.log( obj1 );
--
However, if all you want is to replace all the obj1.values with arr2, all you need is:
obj1.values = [...arr2];
And this will give rise to:
{
count: 8,
id: 'accountId',
name: ' Account Id',
values: [{
count: 20,
id: '432112426686',
name: '432112426686'
},
{
count: 20,
id: '1234456789000',
name: '1234456789000'
}
]
}
DEMO TWO
let obj1 = {
"count": 8,
"id": "accountId",
"name": " Account Id",
"values": [
{
"count": 2,
"id": "1234456789000",
"name": "1234456789000"
},
{
"count": 1,
"id": "135792468045",
"name": "135792468045"
},
{
"count": 1,
"id": "309983110022",
"name": "309983110022"
},
{
"count": 2,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 1,
"id": "6ee26149-a156-4665-bd26-a6e46b49a70f",
"name": "6ee26149-a156-4665-bd26-a6e46b49a70f"
},
{
"count": 1,
"id": "927b48ce-efe4-4c20-98f0-ec6c54f59b45",
"name": "927b48ce-efe4-4c20-98f0-ec6c54f59b45"
}
]
};
let arr2 = [
{
"count": 20,
"id": "432112426686",
"name": "432112426686"
},
{
"count": 20,
"id": "1234456789000",
"name": "1234456789000"
}
];
obj1.values = arr2;
console.log( obj1 );

Flutter return json where id = [31,34]

When I click a button, I want to get a new list. And the example below
i have this list :
List users = [
{
"id": 31,
"name": "John",
},
{
"id": 23,
"name": "Sami",
},
{
"id": 34,
"name": "Leon",
}
];
when search for id list like [31,34]
i need return this result
List users = [
{
"id": 31,
"name": "John",
},
{
"id": 34,
"name": "Leon",
}
];
You can filter it out like this
var newList = users.where((e) => e['id']==31 || e['id']==34).toList();
here is an example:
List users = [
{
"id": 31,
"name": "John",
},
{
"id": 23,
"name": "Sami",
},
{
"id": 34,
"name": "Leon",
}
];
List<searchIds> = [31, 23];
List<searchUsers> = [];
for (int i = 0; i < searchIds.length; i++) {
searchUsers.add(users.where((x) => x["id"] == searchIds[i]).toList()[0]);
}

How to delete objects from array

I want to remove object from array if they dont have a value
i have the API A, that returns to me this JSON:
{
"code": 0,
"data": [
{
"name": {
"value": "Ana"
},
"fruit": {
"value": "Grape"
},
"from": {
"value": "BR"
}
},
{
"name": {
"value": "Michael"
},
"fruit": {
"value": "Apple"
},
"from": {
"value": "US"
}
}
]
}
and with the API B, i can return the id for this user passing her the name
i have this code:
getData() {
this.myService.getDataAPI_A()
.subscribe((res) => {
this.myList = res['data'];
if (this.myList) {
for (const key of this.myList) {
this.getId(key.name.value);
}
}
});
}
getId(name) {
this.myService.getDataAPI_B(name) // api B returns id with the name
.subscribe((res) => {
this.myList.map((tempList) => {
if (res.name === tempList.name.value) {
tempList.userId = res.id; // creating a key and setting value
return tempList;
}
return tempList;
});
});
}
then i got this json:
{
"code": 0,
"custodyBovespa": [
{
"name": {
"value": "Ana"
},
"userId": "43",
"fruit": {
"value": "Grape"
},
"from": {
"value": "BR"
}
},
{
"name": {
"value": "Michael"
},
"fruit": {
"value": "Apple"
},
"from": {
"value": "US"
}
}
]
}
Michael does not existe in my data base, so the api returns to me null,
and for some reason dont create the key in my json (why?).
after this i want to remove the object that dont have userId
how i can do this?
If you'd like your resultant array to contain only objects that contain the property userId, you can simply use plain JavaScript .filter.
In my below example, I am removing any element that does not have a "userId" prop.
var data = [
{
"name": {
"value": "Ana"
},
"userId": "43",
"fruit": {
"value": "Grape"
},
"from": {
"value": "BR"
}
},
{
"name": {
"value": "Michael"
},
"fruit": {
"value": "Apple"
},
"from": {
"value": "US"
}
}
];
var dataFiltered = data.filter(val => val["userId"]);
console.log(dataFiltered);
As you said:
Michael does not existe in my data base
and the condition you set is
if (res.name === tempList.name.value) {
tempList.userId = res.id; // creating a key and setting value
return tempList;
}
return tempList;
As the your database doesn't have the the value 'Michael', The above condition is false. So, it gets out of the if clause and just return what it is without userId.
Now if you want to set the 'Michael' userId to null.
if (res.name === tempList.name.value) {
tempList.userId = res.id; // creating a key and setting value
} else {
tempList.userId = null;
}
return tempList;
Then filter out the data's using like #Rich answered.
console.log(data.filter(val => val['userId'] !== null);

Resources