I'd like to take this array of objects, where some objects contain arrays of a similar schema, and create a new array where they're all on the same level.
[
{
"name": "United States",
"slug": "united-states",
"states":[
{
"name": "Arizona",
"slug": "arizona"
},
{
"name": "California",
"slug": "california"
}
]
},
{
"name": "Canada",
"slug": "canada",
}
]
This should be the end result:
[
{
"name": "United States",
"slug": "united-states"
},
{
"name": "Arizona",
"slug": "arizona"
},
{
"name": "California",
"slug": "california"
},
{
"name": "Canada",
"slug": "canada",
}
]
Using Array#flatMap:
const data = [
{
"name": "United States",
"slug": "united-states",
"states":[
{ "name": "Arizona", "slug": "arizona" },
{ "name": "California", "slug": "california" }
]
},
{ "name": "Canada", "slug": "canada" }
];
const res = data.flatMap(({ name, slug, states = [] }) => ([
{ name, slug },
...states
]));
console.log(res);
You could create an iterator for traversing the tree, and than consume that into an array. This works with deeper nesting levels, and does not need to know which property has the child records. It assumes that the property which has an Array value is holding the subtrees:
function * traverse(forest) {
for (const item of forest) {
const arrayKey = Object.entries(item).find(([k, v]) => Array.isArray(v))?.[0];
const { [arrayKey]: children, ...rest } = item;
yield rest;
if (children) yield * traverse(children);
}
}
const data = [{"name": "United States","slug": "united-states","states":[{ "name": "Arizona", "slug": "arizona" },{ "name": "California", "slug": "california" }]},{ "name": "Canada", "slug": "canada" }];
const res = [...traverse(data)];
console.log(res);
Related
After filtering the data, I am getting below response inside findChildrens function.
Now i am expecting is if this.newRegion have object length more than 1,
than it will merge children of second object inside the parent object children.
For ex - In below Response, i am getting two objects "Africa" and "Europe", So i wanted to merge children of "Europe" inside the parent children of "Africa".
Can anyone please help me to push as my expected output.
findChildrens(){
this.newRegion = [
{
"name": "Africa",
"children": [
{
"name": "Test1",
"region": "1UL Africa"
},
{
"name": "Test2",
"region": "South Africa",
},
{
"name": "Test3",
"region": "New Test",
}
]
},
{
"name": "Europe",
"children": [
{
"name": "Test4",
"region": "1UL Africa"
},
{
"name": "Test5",
"region": "Test Europe"
}
]
}
];
};
};
Expected Output
this.newRegion = [
{
"name": "Africa",
"children": [
{
"name": "Test1",
"region": "1UL Africa"
},
{
"name": "Test2",
"region": "South Africa",
},
{
"name": "Test3",
"region": "New Test",
},
{
"name": "Test4",
"region": "1UL Africa"
},
{
"name": "Test5",
"region": "Test Europe"
}
]
}
];
};
Are you looking to do something like
let newRegion = [
{
"name": "Africa",
"children": [
{
"name": "Test1",
"region": "1UL Africa"
},
{
"name": "Test2",
"region": "South Africa",
},
{
"name": "Test3",
"region": "New Test",
}
]
},
{
"name": "Europe",
"children": [
{
"name": "Test4",
"region": "1UL Africa"
},
{
"name": "Test5",
"region": "Test Europe"
}
]
}
];
let result=newRegion[0];
if(newRegion.length>1){
result.children=result.children.concat(newRegion.slice(1).map(obj=>obj.children).flat())
}
console.log(result)
This function might be what you're looking. But I have to warn you that what you're trying to do is not scalable or representative of code best practices. You might want to edit this code a bit to make it works regardless of how many regions you have.
// It might be preferable to store this in a constant
const REGIONS = [
{
"name": "Africa",
"children": [
{
"name": "Test1",
"region": "1UL Africa"
},
{
"name": "Test2",
"region": "South Africa",
},
{
"name": "Test3",
"region": "New Test",
}
]
},
{
"name": "Europe",
"children": [
{
"name": "Test4",
"region": "1UL Africa"
},
{
"name": "Test5",
"region": "Test Europe"
}
]
}
];
findChildren() {
if (Object.keys(REGIONS).length > 1) {
const mergedChildren = REGIONS[0].children.concat(REGIONS[1].children);
return ({
...REGIONS[0],
children: mergedChildren
})
} else {
return REGIONS[0];
}
}
I'm trying to loop thru products array and find its description in description array. The product id and description parent represent the same product. If the description could be found, push the product with its description to the results array.
I don't really know how this loop should look like.
Products
let products = [
{
"id": "43",
"titel": "Phone",
"price": "211"
},{
"id": "76",
"titel": "Battery",
"price": "34"
},{
"id": "102",
"titel": "Pen",
"price": "45"
},{
"id": "127",
"titel": "Apple",
"price": "10"
}
]
Descriptions
let descriptions= [
{
"description": "Good battery",
"parent": "76"
},{
"description": "Sharp pen",
"parent": "102"
},
]
Expected output results
let results = [
{
"id": "76",
"titel": "Battery",
"price": "34"
"description": "Good battery",
"parent": "76"
},{
"id": "102",
"titel": "Pen",
"price": "45"
"description": "Sharp pen",
"parent": "102"
},
]
You can take advantage of Array.prototype.reduce which allows to transform an array to another type of Object of array.
combine with the Array.prototype.find to check if item with a given id exists in the descriptions Array
let products = [
{
"id": "43",
"titel": "Phone",
"price": "211"
},{
"id": "76",
"titel": "Battery",
"price": "34"
},{
"id": "102",
"titel": "Pen",
"price": "45"
},{
"id": "127",
"titel": "Apple",
"price": "10"
}
]
let descriptions= [
{
"description": "Good battery",
"parent": "76"
},{
"description": "Sharp pen",
"parent": "102"
},
]
const result = products.reduce((acc, item) => {
// Check if the description of the current product exists
let exist = descriptions.find(desc => {
return item.id === desc.parent;
});
if(exist) {
return acc.concat({...item, description: exist.description});
}
return acc;
}, []);
console.log(result);
If you add another array comments you can update the code instead of to concatenate the item in the accumulator directly you'll create another object which after finding the related comment in the comment array you'll add the comment key in that object with their comment.
Here is the code
let products = [
{
"id": "43",
"titel": "Phone",
"price": "211"
},{
"id": "76",
"titel": "Battery",
"price": "34"
},{
"id": "102",
"titel": "Pen",
"price": "45"
},{
"id": "127",
"titel": "Apple",
"price": "10"
}
]
let descriptions= [
{
"description": "Good battery",
"parent": "76"
},{
"description": "Sharp pen",
"parent": "102"
},
]
let comments = [
{
"comment": "Good battery comment",
"product": "76",
}, {
"comment": "Sharp pen comment",
"product": "102"
}
];
const result = products.reduce((acc, item) => {
// Check if the description of the current product exists
let productExists = descriptions.find(desc => {
return item.id === desc.parent;
});
let commentExists = comments.find(comment => {
return item.id === comment.product
});
let newItem = null;
if(productExists) {
newItem = {
...item,
description: productExists.description
};
}
if(commentExists) {
newItem.comment = commentExists.comment;
}
return newItem? acc.concat(newItem): acc;
}, []);
console.log(result);
You should iterate over the descriptions, then use there Array.find and merge them together into a new object, with Object.assign and push them to your results
let products = [
{
"id": "43",
"titel": "Phone",
"price": "211"
},{
"id": "76",
"titel": "Battery",
"price": "34"
},{
"id": "102",
"titel": "Pen",
"price": "45"
},{
"id": "127",
"titel": "Apple",
"price": "10"
}
];
let descriptions= [
{
"description": "Good battery",
"parent": "76"
},{
"description": "Sharp pen",
"parent": "102"
},
];
let results = [];
for (const desc of descriptions) {
const product = products.find(v => v.id === desc.parent);
if (!product) {
continue;
}
results.push(Object.assign({}, product, desc));
}
console.log(results);
const result = descriptions.map(descr => {
const product = products.find(prod => prod.id === descr.parent);
return {...product, ...descr}
})
I am trying to access key pair values on a array object and setstate but it returns undefined
when i console.log(obj) i see the values but when i try to access them it get undefined
const data =[
[
{
"name": "chris",
"city": "unknown",
"code": "404",
"zip": "345"
},{
"name": "kulo mike",
"city": "america",
"code": "210",
"zip": "43"
}, {
"name": "chris smith",
"city": "unknown",
"code": "918",
"zip": "89"
},
]
]
i tried this
const person = data.filter(
item =>{
item.name == 'chris'
console.log(item.name)
})
and also this
const person = data.filter(
item => item.name === 'kulo mike'
)[0].zip
set state
this.state={
user: person
}
Array inside Array, try to convert your data to :
const data =[
{
"name": "chris",
"city": "unknown",
"code": "404",
"zip": "345"
},{
"name": "kulo mike",
"city": "america",
"code": "210",
"zip": "43"
}, {
"name": "chris smith",
"city": "unknown",
"code": "918",
"zip": "89"
},
]
const user = data.filter(item => item.name === 'kulo mike')[0]
setState({user})
I've been searching for something to help me on this particular problem but I've not found a suitable solution which works for my case. I'd really appreciate it if somebody could point me in the right direction.
I have an array:
var ruizTreeData = [
{
"Name": "Ruiz Hernandez",
"parent": "null",
"nodetype": "person",
"Country": "assets/img/aml-flag-1.png",
"children": [
{
"Name": "Checking",
"nodetype": "account",
"Country": "assets/img/aml-flag-1.png",
"children": [
{
"Name": "Renato Godoy",
"nodetype": "person",
"Country": "assets/img/aml-flag-4.png"
},
{
"Name": "Juan Nieto",
"nodetype": "person",
"Country": "assets/img/aml-flag-4.png"
},
{
"Name": "Bani Cortes",
"nodetype": "person",
"Country": "assets/img/aml-flag-2.png"
},
{
"Name": "Medina Marquez",
"nodetype": "person",
"Country": "assets/img/aml-flag-2.png"
}
]
}
]
}
];
I have another function which is creating an object, and what I'd like to do is insert that object into this "tree" at a particular index. So for example, the user would choose to insert a new person underneath "Ruiz Hernandez", so I'd create an object which would be a sibling of "Checking". But I want it to be flexible enough so that if somebody added as a child of "Checking" we'd do the same, or a child of "Bani Cortes" we'd do the same etc.
I'm thinking I'd have to iterate ruizTreeData until I found "Ruiz Hernandez" and then insert the object into the children array of "Ruiz Hernandez".
So the array would then look like:
var ruizTreeData = [
{
"Name": "Ruiz Hernandez",
"parent": "null",
"nodetype": "person",
"Country": "assets/img/aml-flag-1.png",
"children": [
{
"Name": "Checking",
"nodetype": "account",
"Country": "assets/img/aml-flag-1.png",
"children": [
{
"Name": "Renato Godoy",
"nodetype": "person",
"Country": "assets/img/aml-flag-4.png"
}...
]
},
{
"Name": "Inserted object",
"nodetype": "account",
"Country": "assets/img/aml-flag-1.png"
}
]
}
];
I've tried a bunch of things, the closest I've got is:
positionInTree = ruizTreeData
.map(function (element) {return element["Name"];})
.indexOf("Ruiz Hernandez");
But this only returns at the first index, it doesn't go into the nested objects. Would I need a for loop for this?
I'd really appreciate some help with this. Thanks very much.
There you go. You can select your element by a key/value identifier and this function will create a children property if there isn't one already with your object inside it or add your object into the already existing children property.
I added a person named Ruiz Hernandez into the last node (Checking's children) to show you how the function add your object in every node with your key/value identifier.
var ruizTreeData = [
{
"Name": "Ruiz Hernandez",
"parent": "null",
"nodetype": "person",
"Country": "assets/img/aml-flag-1.png",
"children": [
{
"Name": "Checking",
"nodetype": "account",
"Country": "assets/img/aml-flag-1.png",
"children": [
{
"Name": "Renato Godoy",
"nodetype": "person",
"Country": "assets/img/aml-flag-4.png"
},
{
"Name": "Juan Nieto",
"nodetype": "person",
"Country": "assets/img/aml-flag-4.png"
},
{
"Name": "Bani Cortes",
"nodetype": "person",
"Country": "assets/img/aml-flag-2.png"
},
{
"Name": "Ruiz Hernandez",
"nodetype": "person",
"Country": "assets/img/aml-flag-2.png"
},
{
"Name": "Medina Marquez",
"nodetype": "person",
"Country": "assets/img/aml-flag-2.png"
}
]
}
]
}
];
Array.prototype.addChild = function(key, value, object){
let el;
if(this.find(x => x[key] == value)){
this.filter(x => x[key] == value).forEach(y => y.children = (y.children) ? [...y.children, {...object}] : [{...object}])
}
this.forEach(y => {
if(y.children){
y.children.addChild(key, value, object);
}
});
}
ruizTreeData.addChild("Name", "Ruiz Hernandez", {Name: "Name"});
console.log(ruizTreeData);
I'm not sure the best way to go about this. I want to iterate my json and find all companies that are in the US for example. This JSON might get way more complex as my app grows too, as in levels, objects, etc. I just want to know ways people are doing simple searching for filtering out subsets of data with JSON and Node.js and/or ES6 or libraries maybe such as Lodash, etc.
So for example this json, what are some ways I can search it and pull back only those companies in the USA?
[{
"id": 0,
"name": "Company1",
"logoUrl": "/lib/assets/company1-logo.png",
"location":{
"country": "USA",
"state": "California",
"city": "Napa"
},
"active": false
},
{
"id": 1,
"name": "Company2",
"logoUrl": "/lib/assets/company2-logo.png",
"location":{
"country": "Germany",
"state": "",
"city": "Berlin"
},
"active": false
},
{
"id": 2,
"name": "Company3",
"logoUrl": "/lib/assets/company3-logo.png",
"location":{
"country": "USA",
"state": "Michigan",
"city": "Detroit"
},
"active": false
}]
Use JavaScript native Array#filter method with ES6 arrow function
var res = data.filter(v => v.location.country === 'USA');
var data = [{
"id": 0,
"name": "Company1",
"logoUrl": "/lib/assets/company1-logo.png",
"location": {
"country": "USA",
"state": "California",
"city": "Napa"
},
"active": false
}, {
"id": 1,
"name": "Company2",
"logoUrl": "/lib/assets/company2-logo.png",
"location": {
"country": "Germany",
"state": "",
"city": "Berlin"
},
"active": false
}, {
"id": 2,
"name": "Company3",
"logoUrl": "/lib/assets/company3-logo.png",
"location": {
"country": "USA",
"state": "Michigan",
"city": "Detroit"
},
"active": false
}];
var res = data.filter(v => v.location.country === 'USA');
console.log(res);
You can use JavaScript's simple .filter() method to return the list of results fulfilling the filter. Say your data is in variable data
ES5
data.filter(function(item) {
return item.location.country === 'USA';
});
ES6: In ES6 you can use arrow functions for same as
data.filter((item) => {
return item.location.country === 'USA';
});
var data = [{
"id": 0,
"name": "Company1",
"logoUrl": "/lib/assets/company1-logo.png",
"location":{
"country": "USA",
"state": "California",
"city": "Napa"
},
"active": false
},
{
"id": 1,
"name": "Company2",
"logoUrl": "/lib/assets/company2-logo.png",
"location":{
"country": "Germany",
"state": "",
"city": "Berlin"
},
"active": false
},
{
"id": 2,
"name": "Company3",
"logoUrl": "/lib/assets/company3-logo.png",
"location":{
"country": "USA",
"state": "Michigan",
"city": "Detroit"
},
"active": false
}];
var res1 = data.filter(function(item) {
return item.location.country === 'USA';
});
const res2 = data.filter((item) => {
return item.location.country === 'USA';
});
console.log(res1);
console.log(res2);
In lodash it will be
_.filter(data, function(item) {
return item.location.country === 'USA';
});
You can use native filter function.
const items = [{
"id": 0,
"name": "Company1",
"logoUrl": "/lib/assets/company1-logo.png",
"location":{
"country": "USA",
"state": "California",
"city": "Napa"
},
"active": false
},
{
"id": 1,
"name": "Company2",
"logoUrl": "/lib/assets/company2-logo.png",
"location":{
"country": "Germany",
"state": "",
"city": "Berlin"
},
"active": false
},
{
"id": 2,
"name": "Company3",
"logoUrl": "/lib/assets/company3-logo.png",
"location":{
"country": "USA",
"state": "Michigan",
"city": "Detroit"
},
"active": false
}]
const usItems = items.filter(v => v.location.country === 'USA')