How to create an array based on two array - javascript

I have an array of object, this array contains differents names.
[ "Foo", "Bar", "Test", "Other" ];
And another array of object
[ { name:"Bar", value: 159 }, { name: "Foo", value: 120 }, { name: "Other", value: 1230 } ]
I need to create an array of them, the new array contains sub array with a size of 2, first index the name and second index the value.
The order of the array need to be the same of the first one (array of names).
Like
[ ["Foo", 120], ["Bar", 159], ["Test", undefined], ["Other", 1230] ]
So I try this code, but my output is not correct. The order of name is correct but the order of value is not.
var order = ["Foo", "Bar", "Test", "Other"];
var values = [{ name: "Bar", value: 159 }, { name: "Foo", value: 120 }, { name: "Other", value: 1230 }];
var array = order.map(function(name, i) {
return [name, (values[i] && values[i].value) ];
})
console.log(array)

You could take a Map and get the items in the wanted order.
var names = [ "Foo", "Bar", "Test", "Other" ],
objects = [{ name: "Bar", value: 159 }, { name: "Foo", value: 120 }, { name: "Other", value: 1230 }],
map = new Map(objects.map(({ name, value }) => [name, value])),
result = names.map(name => [name, map.get(name)])
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

You're nearly there - you just need to find the correct value:
var order = ["Foo", "Bar", "Test", "Other"];
var values = [{ name: "Bar", value: 159 }, { name: "Foo", value: 120 }, { name: "Other", value: 1230 }];
var array = order.map(function(name, i) {
return [name, values.some(e => e.name == name) ? values.find(e => e.name == name).value : undefined];
})
console.log(array)
ES5 syntax:
var order = ["Foo", "Bar", "Test", "Other"];
var values = [{ name: "Bar", value: 159 }, { name: "Foo", value: 120 }, { name: "Other", value: 1230 }];
var array = order.map(function(name, i) {
return [name, values.some(function(e) {
return e.name == name;
}) ? values.find(function(e) {
return e.name == name;
}).value : undefined];
});
console.log(array)

Check out my solution. Hope this helps.
const a = [ "Foo", "Bar", "Test", "Other" ];
const b = [ { name:"Bar", value: 159 }, { name: "Foo", value: 120 }, { name: "Other", value: 1230 } ];
const res = a.map((item) => [ item, (b.find(({ name }) => name === item) || {}).value ])
console.log(res)

You need to use entries in "order" to lookup "name" in values
var order = ["Foo", "Bar", "Test", "Other"];
var values = [{ name: "Bar", value: 159 }, { name: "Foo", value: 120 }, { name: "Other", value: 1230 }];
var array = order.map(function(key, i) {
let found = values.find(({name}) => name === key);
return [key, found && found.value ];
})
console.log(array)

You could use map and take the Object.values of the found item, or a default one
const arr1 = [ "Foo", "Bar", "Test", "Other" ];
const arr2 = [ { name:"Bar", value: 159 }, { name: "Foo", value: 120 }, { name: "Other", value: 1230 } ];
const res = arr1.map(e => Object.values(arr2.find(({name}) => name === e) || ({name: e, value: undefined})));
console.log(res);

var order = ["Foo", "Bar", "Test", "Other"];
var values = [{ name: "Bar", value: 159 }, { name: "Foo", value: 120 }, { name: "Other", value: 1230 }];
var result = [];
orders.forEach((f) => {
let found = false;
values.forEach(s => {
if (f === s.name) {
result.push([f, s.value]);
found = true;
}
});
if (!found) {
result.push([f, undefined]);
}
});

Related

Recursively Transform my JSON data with JS

I'm trying to figure out how to transform some JSON i'm getting back from a web service so i can easily parse it into a nice type-safe object. I want to transform this format from:
[{
"name": "AwesomePeople",
"value": [
[{
"name": "TypeId",
"value": 1
}, {
"name": "People",
"value": [
[{
"name": "id",
"value": 2
}, {
"name": "name",
"value": "Danno"
}
],
[{
"name": "id",
"value": 3
}, {
"name": "name",
"value": "Julio"
}
]
]
}
],
[{
"name": "TypeId",
"value": 2
}, {
"name": "People",
"value": [
[{
"name": "id",
"value": 4
}, {
"name": "name",
"value": "Jenna"
}
],
[{
"name": "id",
"value": 5
}, {
"name": "name",
"value": "Coolio"
}
]
]
}
]
]
}
]
To the following format:
[{
"AwesomePeople": [
[{
"TypeId": 1,
}, {
"People": [
[{
"id": 2
}, {
"firstName":"Danno"
}
],
[{
"id": 3,
}, {
"firstName": "Julio"
}
]
]
}
],
[{
"TypeId": 2
}, {
"People": [
[{
"id": 4
}, {
"firstName": "Jenna"
}
],
[{
"id": 5
}, {
"firstName": "Coolio"
}
]
]
}
]
]
}
];
Two main things need to happen, these stupid "name"/"value" pairs need to be swapped at any and all levels. For example, instead of "name": "id", "value": "3", it would be simply be "id":3. The values are sometimes are arrays, so they need to processed in a similar way...the depth is variable, so i can't assume a certain number of levels deep, so i need to keep processing everything recursively.
I have started playing with the following code...you'll see an empty "newResult" array that i'm trying to build as i traverse the original JSON, taking different action whether i'm currently looking at an object, an array, or a key/property.
let count = 0;
let result = <the original array above>
let newResult = [];
result.forEach(function(resObj) {
console.log("STARTING to TRAVERSE HIGHER LEVEL OBJECTS!");
traverse(resObj);
count++;
//we're done processing high level objects, so return from this function and enjoy the newResult!
if (count===result.length)
//return from this function
console.log(newResult);
console.log("FINISHED PROCESSING HIGHER LEVEL OBJECTS, SO DONE!");
});
//Below are the functions for traversing
function traverse(x, level) {
if (isArray(x)) {
console.log("array");
traverseArray(x);
} else if ((typeof x === 'object') && (x !== null)) {
console.log("object");
traverseObject(x);
} else {
console.log("property: "+x);
//console.log(level + x);
}
}
function isArray(o) {
return Object.prototype.toString.call(o) === '[object Array]';
}
function traverseArray(arr, level) {
//console.log(level + "<array>");
arr.forEach(function(x) {
traverse(x);
});
}
function traverseObject(obj, level) {
var keyName, keyValue;
//console.log(level + "<object>");
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (key==="name"){
keyName = obj[key];
}else if (key==="value"){
keyValue = obj[key];
}
if (keyName && keyValue){
var newObj = {[keyName]: keyValue}
newResult.push(newObj);
//console.log("the KEY NAME IS: "+ keyName + ", and the VALUE is: "+keyValue);
}
//if we have a key value, but the value is an array, stop and
// if (isArray(newOj)
console.log("traversing..." +obj[key]);
traverse(obj[key]);
}//end if property
}//end foreach key in object
}//end traverseObject
thanks all...kudos to the person who can get their brain around this :)
You can do this with JSON.stringify and JSON.parse - with a reviver, check if the value has a name property, and if it does, return { [value.name]: value.value }:
const arr=[{name:"AwesomePeople",value:[[{name:"TypeId",value:1},{name:"People",value:[[{name:"id",value:2},{name:"name",value:"Danno"}],[{name:"id",value:3},{name:"name",value:"Julio"}]]}],[{name:"TypeId",value:2},{name:"People",value:[[{name:"id",value:4},{name:"name",value:"Jenna"}],[{name:"id",value:5},{name:"name",value:"Coolio"}]]}]]}];
const result = JSON.parse(JSON.stringify(arr, (key, value) => (
value?.name
? { [value.name]: value.value }
: value
)));
console.log(result);
If you also want to change the name values to firstName keys, add a conditional in the computed property:
const arr=[{name:"AwesomePeople",value:[[{name:"TypeId",value:1},{name:"People",value:[[{name:"id",value:2},{name:"name",value:"Danno"}],[{name:"id",value:3},{name:"name",value:"Julio"}]]}],[{name:"TypeId",value:2},{name:"People",value:[[{name:"id",value:4},{name:"name",value:"Jenna"}],[{name:"id",value:5},{name:"name",value:"Coolio"}]]}]]}];
const result = JSON.parse(JSON.stringify(arr, (key, value) => (
value?.name
? { [value.name === 'name' ? 'firstName' : value.name]: value.value }
: value
)));
console.log(result);
Manually:
const arr=[{name:"AwesomePeople",value:[[{name:"TypeId",value:1},{name:"People",value:[[{name:"id",value:2},{name:"name",value:"Danno"}],[{name:"id",value:3},{name:"name",value:"Julio"}]]}],[{name:"TypeId",value:2},{name:"People",value:[[{name:"id",value:4},{name:"name",value:"Jenna"}],[{name:"id",value:5},{name:"name",value:"Coolio"}]]}]]}];
const recurse = (val) => {
if (!val || typeof val !== 'object') return val;
if (Array.isArray(val)) return val.map(recurse);
return { [val.name === 'name' ? 'firstName' : val.name]: val.value };
};
const result = recurse(arr);
console.log(result);
I grabbed your data, quickly wrote a function to convert it, came to post it and realized that my output wasn't at all what you requested. I would just throw it away, except that it seems to me this output is much more useful than what you requested. So if you can use something like this:
{
AwesomePeople: [
{
TypeId: 1,
People: [
{id: 2, name: "Danno"},
{id: 3, name: "Julio"}
]
},
{
TypeId: 2,
People: [
{id: 4, name: "Jenna"},
{id: 5, name: "Coolio"}
]
}
]
}
then this function may help:
const convert = (xs) =>
Object .fromEntries (
xs .map (({name, value}) => [
name,
Array .isArray (value) ? value .map (convert) : value
])
)
const data = [{name: "AwesomePeople", value: [[{name: "TypeId", value: 1}, {name: "People", value: [[{name: "id", value: 2}, {name: "name", value: "Danno"}], [{name: "id", value: 3}, {name: "name", value: "Julio"}]]}], [{name: "TypeId", value: 2}, {name: "People", value: [[{name: "id", value: 4}, {name: "name", value: "Jenna"}], [{name: "id", value: 5}, {name: "name", value: "Coolio"}]]}]]}]
console .log (convert (data))
.as-console-wrapper {min-height: 100% !important; top: 0}
If not, well then maybe someone else might get some use out of it.
Here is an answer using object-scan. This code modifies the original input, which can be significantly faster than rebuilding the structure.
Note that in your input the data is a bit inconsistent: Where does firstName come from? So I've assumed consistency
// const objectScan = require('object-scan');
const data = [{ name: 'AwesomePeople', value: [ [{ name: 'TypeId', value: 1 }, { name: 'People', value: [ [{ name: 'id', value: 2 }, { name: 'name', value: 'Danno' } ], [{ name: 'id', value: 3 }, { name: 'name', value: 'Julio' } ] ] } ], [{ name: 'TypeId', value: 2 }, { name: 'People', value: [ [{ name: 'id', value: 4 }, { name: 'name', value: 'Jenna' } ], [{ name: 'id', value: 5 }, { name: 'name', value: 'Coolio' } ] ] } ] ] } ];
objectScan(['**[*].name'], {
filterFn: ({ parent }) => {
const { name, value } = parent;
delete parent.name;
delete parent.value;
parent[name] = value;
}
})(data);
console.log(data);
// => [ { AwesomePeople: [ [ { TypeId: 1 }, { People: [ [ { id: 2 }, { name: 'Danno' } ], [ { id: 3 }, { name: 'Julio' } ] ] } ], [ { TypeId: 2 }, { People: [ [ { id: 4 }, { name: 'Jenna' } ], [ { id: 5 }, { name: 'Coolio' } ] ] } ] ] } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan#14.0.0"></script>
Disclaimer: I'm the author of object-scan

Merge 2 objects in an array where the values are an array

I am trying to merge values in 2 objects from the same array. The objects in this case are similar and the values I want to merge are arrays(Set)
var array = [
{
name: "foo1",
value: ["val1","val2"]
},
{
name: "foo1",
value: ["val2", "val3"]
},
{
name: "foo2",
value: ["val4"]
},
{
name: "foo2",
value: ["val4","val5"]
},
];
Expected Output
[
{
name: "foo1",
value: ["val1","val2", "val3"]
},{
name: "foo2",
value: ["val4","val4", "val5"]
}
]
My Code
var output = [];
array.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.name == item.name;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
let newValue = new Set(output[existingIndex].value).add(item.value)
output[existingIndex].value = Array.from(newValue);
} else {
output.push(item);
}
});
Output Gotten
[ {
name: "foo1",
value: ["val1", "val2", ["val2", "val3"]]
}, {
name: "foo2",
value: ["val4", ["val4", "val5"]]
}]
How can I get the expected output (ES6 would also be preferred)
Try this
const array = [
{
"name": "foo1",
"value": [
"val1",
"val2",
"val3"
]
},
{
"name": "foo1",
"value": [
"val2",
"val3"
]
},
{
"name": "foo2",
"value": [
"val4",
"val5"
]
},
{
"name": "foo2",
"value": [
"val4",
"val5"
]
}
]
const result = []
for (const item of array) {
const existingItem = result.find(i => i.name === item.name)
if (existingItem) {
existingItem.value = [...new Set([...existingItem.value, ...item.value])]
} else {
result.push(item)
}
}
console.log(result)
Is this code solve your problem?
var array = [
{
name: "foo1",
value: ["val1","val2"]
},
{
name: "foo1",
value: ["val2", "val3"]
},
{
name: "foo2",
value: ["val4"]
},
{
name: "foo2",
value: ["val4","val5"]
},
];
var output = [];
array.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.name == item.name;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
let newValue = new Set(output[existingIndex].value.concat(item.value))
output[existingIndex].value = Array.from(newValue);
} else {
output.push(item);
}
});
try
var arr = [
{
name: "foo1",
value: ["val1","val2"]
},
{
name: "foo1",
value: ["val2", "val3"]
},
{
name: "foo2",
value: ["val4"]
},
{
name: "foo2",
value: ["val4","val5"]
},
];
var arr2={}
arr.map((elem,ind)=>{
if(!arr2[elem.name]){
arr2[elem.name]=[]
}
arr2[elem.name]=[...arr2[elem.name],...elem.value]
})
arr=Object.keys(arr2);
arr.map((elem,ind)=>{
arr[ind]={name:elem,value:arr2[elem]};
})
You can do the following using reduce,
var array = [
{
name: "foo1",
value: ["val1","val2"]
},
{
name: "foo1",
value: ["val2", "val3"]
},
{
name: "foo2",
value: ["val4"]
},
{
name: "foo2",
value: ["val4","val5"]
},
];
res = array.reduce((prev, curr) => {
let index = prev.findIndex(item => item.name === curr.name);
if(index > -1) {
s = new Set([...prev[index].value, ...curr.value]);
prev[index].value = Array.from(s);
} else {
prev.push(curr);
}
return prev;
},[]);
console.log(res);
You could use reduce method with a Map as accumulator value and then use spread syntax ... on Map values to get an array of values.
var array = [{"name":"foo1","value":["val1","val2","val2","val3"]},{"name":"foo1","value":["val2","val3"]},{"name":"foo2","value":["val4","val4","val5"]},{"name":"foo2","value":["val4","val5"]}]
const map = array.reduce((r, { name, value }) => {
if (!r.has(name)) r.set(name, { name, value })
else r.get(name).value.push(...value)
r.get(name).value = [...new Set(r.get(name).value)]
return r;
}, new Map)
const result = [...map.values()]
console.log(result)
One approach is to create an unique list of keys and iterate over it. Create an array for each key and merge the values. The vanilla js way is:
Array.from(new Set(array.map(el => el.name)))
.map(name => ({
name,
value: Array.from(new Set(array.filter(el => el.name === name).flatMap(el => el.value)))
}))
Example:
const array = [
{
name: "foo1",
value: ["val1","val2"]
},
{
name: "foo1",
value: ["val2", "val3"]
},
{
name: "foo2",
value: ["val4"]
},
{
name: "foo2",
value: ["val4","val5"]
},
];
console.log(Array.from(new Set(array.map(el => el.name)))
.map(name => ({
name,
value: Array.from(new Set(array.filter(el => el.name === name).flatMap(el => el.value)))
})));
Using lodash you can reduce it to
_.uniq(array.map(el => el.name))
.map(name => ({
name,
value: _.uniq(array.filter(el => el.name === name).flatMap(el => el.value))
}))
Example:
const array = [
{
name: "foo1",
value: ["val1","val2"]
},
{
name: "foo1",
value: ["val2", "val3"]
},
{
name: "foo2",
value: ["val4"]
},
{
name: "foo2",
value: ["val4","val5"]
},
];
console.log(_.uniq(array.map(el => el.name))
.map(name => ({
name,
value: _.uniq(array.filter(el => el.name === name).flatMap(el => el.value))
})));
<script src="https://cdn.jsdelivr.net/npm/lodash#4.17.20/lodash.min.js"></script>
Find unique values of keys. Match this keys within array and return unique objects. Push this objects in an empty array. Then match other objects value with the new arrays objects value and push the unmatched values to this new array.
var arr = [
{
name: "foo1",
value: ["val1","val2"]
},
{
name: "foo1",
value: ["val2", "val3"]
},
{
name: "foo2",
value: ["val4"]
},
{
name: "foo2",
value: ["val4","val5"]
},
];
let key = [];
arr.map((val)=>key.push(val.name));
let uniquekeys = [...new Set(key)]; //unique values of keys
let newarr = [];
uniquekeys.map((uniquekey,ind)=>{
let reduceunique = arr.filter((vals)=>uniquekey == vals.name); // return matching objects as array
newarr.push(reduceunique[0]); // Push unique objects in an empty array
for(let i = 1; i<uniquekeys.length;i++){
reduceunique[i].value.map((val)=>{
let existvalue = newarr[ind].value.indexOf(val); // Match every value with the unique objects values
if(existvalue<0){
newarr[ind].value.push(val); // push the unmatched value in the array
}
});
};
});
console.log(newarr);
try to use Array.reduce and Array.filter to get the result like the following
var array = [
{
name: "foo1",
value: ["val1","val2"]
},
{
name: "foo1",
value: ["val2", "val3"]
},
{
name: "foo2",
value: ["val4"]
},
{
name: "foo2",
value: ["val4","val5"]
},
];
res = array.reduce((prev, curr) => {
let index = prev.findIndex(item => item.name === curr.name);
if(index > -1) {
prev[index].value = [...prev[index].value, ...curr.value];
prev[index].value = prev[index].value.filter((v,i) => prev[index].value.indexOf(v) === i)
} else {
prev.push(curr);
}
return prev;
},[]);
console.log(res);

Remove duplicates objects from array by name and max category

How should I remove duplicate objects with the condition?
suppose I have this array :
let my_array = [
{ name: "foo", version: "10" },
{ name: "foo", version: "60" },
{ name: "foo", version: "20" },
{ name: "bar", version: "400" },
];
I need to keep the object that has latest version in it from duplicates.
I know I can use Set for removing dups :
let unique = my_array.filter((set => f =>
!set.has(f.name) && set.add(f.name)
)
(new Set)
)
the expected result with condition of max version is :
let my_array = [
{ name: "foo", version: "60" },
{ name: "bar", version: "400" },
];
Use object.Values and reduce to remove duplicates and get max version of each name.
Demo
let my_array = [
{ name: "foo", version: "10" },
{ name: "foo", version: "60" },
{ name: "foo", version: "20" },
{ name: "bar", version: "400" },
];
let unique = Object.values(my_array.reduce((r, x) => {
r[x.name] = r[x.name] && r[x.name].version > x.version ? r[x.name] : x
return r
}, {}))
console.log(unique )
You can achieve the result by using reduce
let my_array = [{
name: "foo",
version: "10"
},
{
name: "foo",
version: "60"
},
{
name: "foo",
version: "20"
},
{
name: "bar",
version: "400"
},
];
var new_array = my_array.reduce((max, b) => Math.max(max, b.version), my_array[0].version);
console.log(new_array)

Map an array as per true or false set in another array

I have an array of item "mockData" & a Filter array "filter" in angular 8:
filter=[
{column:"name",show:true},
{column:"Sex",show:false},
];
mockData=[
{name:"test",sex:"m"},
{name:"test2",sex:"m"},
{name:"test3",sex:"f"},
{name:"test4",sex:"f"},
];
I want to map only the columns of mockData which are set as true in filter array.
result should look something like this.
[
{name:"test"},
{name:"test2"},
{name:"test3"},
{name:"test4"},
]
it should check in filter mandatorily.
const filter = [
{
column: "name",
show: true
},
{
column: "sex",
show: false
}
];
const mockData = [
{
name: "test",
sex: "m"
},
{
name: "test2",
sex: "m"
},
{
name: "test3",
sex: "f"
},
{
name: "test4",
sex: "f"
}
];
const filteredMockData = mockData.map(data =>
Object.entries(data).reduce(
(result, [key, value]) =>
filter.find(f => f.column === key && f.show)
? { ...result, [key]: value }
: result,
{}
)
);
console.log(filteredMockData);

How to recursively transform an array of nested objects into array of flat objects?

I have the following array of deeply nested objects:
const data = [
{
name: "foo",
children:[
{
count: 1,
name: "A"
},
{
count: 2,
name: "B"
}
]
},
{
name: "bar",
children: [
{
count: 3,
name: "C",
children: [
{
count: 4,
name: "D"
}
]
}
]
}
]
The way I'd like to transform this would be such as:
const expectedStructure = [
{
count: 1,
name: "A",
label: "foo = A"
},
{
count: 2,
name: "B",
label: "foo = B"
},
{
count: 3,
name: "C",
label: "bar = C"
},
{
count: 4,
name: "D",
label: "bar = D"
}
]
I created recursive function that transforms nested array into array of flat objects.
Here's my code:
function getChildren(array, result=[]) {
array.forEach(({children, ...rest}) => {
result.push(rest);
if(children) {
getChildren(children, result);
}
});
return result;
}
And here's output I get:
[ { name: 'foo' },
{ count: 1, name: 'A' },
{ count: 2, name: 'B' },
{ name: 'bar' },
{ count: 3, name: 'C' },
{ count: 4, name: 'D' } ]
The problem is that I need to add label field to every object in my output array, and I can't find a solution without iterating multiple times through the final array to make desired transformation. How to properly insert label field without hugely augmenting complexity of the function?
Check each iteration whether the current item is a "parent" item, and reassign label if it is.
const data = [{name:"foo",children:[{count:1,name:"A"},{count:2,name:"B"}]},{name:"bar",children:[{count:3,name:"C",children:[{count:4,name:"D"}]}]}];
function getChildren(array, result = [], label = "") {
array.forEach(({ children, name, count }) => {
if (!label || name[1]) {
label = `${name} = `;
}
if (count) {
result.push({ count, name, label: label + name });
}
if (children) {
getChildren(children, result, label);
}
});
return result;
}
const res = getChildren(data);
console.log(res);
You can use a different function for the nested levels, so you can pass the top-level name properties down through all those recursion levels.
function getTopChildren(array, result = []) {
array.forEach(({
name,
children
}) => {
if (children) {
getChildren(children, name, result);
}
});
return result;
}
function getChildren(array, name, result) {
array.forEach(({
children,
...rest
}) => {
rest.label = `${name} = ${rest.name}`;
result.push(rest);
if (children) {
getChildren(children, name, result);
}
});
}
const data = [{
name: "foo",
children: [{
count: 1,
name: "A"
},
{
count: 2,
name: "B"
}
]
},
{
name: "bar",
children: [{
count: 3,
name: "C",
children: [{
count: 4,
name: "D"
}]
}]
}
]
console.log(getTopChildren(data));
You can also do this recursively with flatMap based on whether or not a parent has been passed into the recursive call :
const data = [{
name: "foo",
children: [{
count: 1,
name: "A"
},
{
count: 2,
name: "B"
}
]
},
{
name: "bar",
children: [{
count: 3,
name: "C",
children: [{
count: 4,
name: "D"
}]
}]
}
];
function flatten(arr, parent = null) {
return parent
? arr.flatMap(({name, count, children}) => [
{name, count, label: `${parent} = ${name}`},
...flatten(children || [], parent)
])
: arr.flatMap(({name, children}) => flatten(children || [], name));
}
console.log(flatten(data));
Sometimes it's a little easier to reason about the code and write it clearly using generators. You can yield* from the recursive calls:
const data = [{name: "foo",children:[{count: 1,name: "A"},{ count: 2,name: "B"}]},{name: "bar",children: [{count: 3,name: "C",children: [{count: 4,name: "D"}]}]}]
function* flat(input, n){
if (!input) return
if (Array.isArray(input)) {
for (let item of input)
yield* flat(item, n)
}
let _name = n || input.name
if ('count' in input) {
yield { count:input.count, name:input.name, label:`${_name} = ${input.name}`}
}
yield* flat(input.children, _name)
}
let g = [...flat(data)]
console.log(g)
The function returns a generator, so you need to spread it into a list [...flat(data)] if you want a list or iterate over it if you don't need to store the list.

Categories