I want to store this data to mongodb, But I don't know how to loop it, Tried for a long time and couldn't get the correct answer
There is tree data
[
{
name: 'A',
children: [
{
name: 'A1',
children: [
{
name: 'A11',
children: []
}
]
},
{
name: 'A2',
children: []
},
]
},
{
name: 'B',
children: [
{
name: 'B1',
children: []
},
{
name: 'B2',
children: [
{
name: 'B21',
children: []
}
]
},
]
},
]
There is my Schema
const TempSchema = new mongoose.Schema({
name: String,
parent: { type: ObjectId, ref: 'Temp' },
}
I hope to get this result
{ _id: 5dea0671855f5d4b44774afd, name: 'A', parent: null, },
{ _id: 5dea07383ef7973e80883efd, name: 'A1', parent: 5dea0671855f5d4b44774afd, },
{ _id: 5dea07461047036d7c958771, name: 'A11', parent: 5dea07383ef7973e80883efd, },
{ _id: 5def00c05de2b22f8e6b9bfe, name: 'A2', parent: 5dea0671855f5d4b44774afd, },
...
This problem has troubled me for a long time, hope to get everyone's help, thank you!
Create ID and flat
const ObjectId = mongoose.Types.ObjectId;
const flatten = (data, parent = null) =>
data.flatMap(e => {
e._id = ObjectId();
return ([{
_id: e._id,
parent,
name: e.name
},
...flatten(e.children, e._id)])
});
const result = flatten(tree);
await Model.insertMany(result)
Related
I have an array of objects as the following
const sample = [
{ id: '1' },
{ id: '1.1' },
{ id: '1.1.1' },
{ id: '1.1.2' },
{ id: '1.2' },
{ id: '1.2.1' },
{ id: '1.2.1.1' },
{ id: '2' },
{ id: '2.1' }
];
I'd like to create a new array to include the children under their parent based on id property as the following
[
{
id: '1',
children: [
{
id: '1.1',
children: [
{ id: '1.1.1' },
{ id: '1.1.2' }
]
},
{
id: '1.2',
children: [
{
id: '1.2.1',
children: [{ id: '1.2.1.1' }]
}
]
}
]
},
{
id: '2',
children: [ { id: '2.1' } ]
}
]
I'm not sure how to do it or from where to start
Use a map to keep track of parents and children, then get the entries that are the roots as your result:
const data = [
{ id: '1' },
{ id: '1.1' },
{ id: '1.1.1' },
{ id: '1.1.2' },
{ id: '1.3' },
{ id: '1.3.1' },
{ id: '1.3.1.1' },
{ id: '2' },
{ id: '2.1' }
];
const map = new Map();
data.forEach(({ id }) => {
// exclude last bit to get parent id
const parent = id.split(".").slice(0, -1).join(".");
// our entry - needs to be like this since
// we want a reference to the same object
const entry = { id, children: [] };
// won't run if this is a root
if (parent)
// add child to parent
map.get(parent).children.push(entry);
// add to map
map.set(id, entry);
});
const result = Array.from(map)
// get roots - keys that only have one part
.filter(([key]) => key.split(".").length === 1)
// map to entry values
.map(([, value]) => value);
console.log(result);
.as-console-wrapper { max-height: 100% !important }
I have an array with objects. I need to find item with current name and change it.
const example = [
{
id: '1234',
desc: 'sample1',
items: [
itemsName: [
{ id: 1, name: 'name1' },
{ id: 2, name: 'testItem2' }
],
id: 888,
]
},
{
id: '3456',
desc: 'sample2',
items: [
itemsName: [
{ id: 1, name: 'name2' },
{ id: 2, name: 'testItem3' }
],
id: 889,
]
},
I try to do in this way, but it's not working.
I get construction like (5)
[Array(1), Array(1)]
instead of
[{…}, {…}]
const findName = (name, changedName) => {
const result = example?.map((group) =>
group.items.map((group) =>
group.itemsName?.map((i) => {
if (i.name === name) return i.name === changedName;
return null;
})
)
);
}
findName('name1', 'name2')
let findName1 = (name, changedName) => {
const result = example?.map((group) =>
group.items.map((group) =>
group.itemsName?.map((i) => {
if (i.name === name) return i.name = changedName;
return null;
})
)
);
}
This will work with following object (your object declaration seems to be wrong)
const example = [
{
id: '1234',
desc: 'sample1',
items: [
{itemsName: [
{ id: 1, name: 'name1' },
{ id: 2, name: 'testItem2' }
],
id: 888,}
]
},
{
id: '3456',
desc: 'sample2',
items: [
{itemsName: [
{ id: 1, name: 'name2' },
{ id: 2, name: 'testItem3' }
],
id: 889,}
]
}]
Here is my object. There could be children inside of children and so on.
I Am trying to print only name for all of them.
Here is JSFiddle
var products = [
{
name: 'Allison',
children: [
{
name: 'John',
children: [
{
name: 'Scott',
children: [],
},
],
},
{
name: 'Sarah',
children: [],
},
]
},
{
name: 'Tony',
children: [
{
name: 'Lucy',
children: [],
}
]
}
This is what I have tried so far, how can I Print name of all children regardless of what level they are in the object??
for(var i = 0; i < products.length; i++)
{
console.log(products[i].name);
if(products[i].children.length > 0) {
console.log(products[i].children);
// Print only name of all children.
}
}
You can use recursive technical.
var products = [ { name: 'Allison', children: [{ name: 'John', children: [ { name: 'Scott', children: [],},],},{ name: 'Sarah', children: [],},]},{name: 'Tony',children: [{name: 'Lucy',children: [],}]}];
const printRecursively = (products) => {
for (const k of products)
{
console.log(k.name);
k.children.length > 0 && printRecursively(k.children); // Recurive here.
}
}
printRecursively(products);
Here is the implementation, please check
Also here
var products = [
{
name: 'Allison',
children: [
{
name: 'John',
children: [
{
name: 'Scott',
children: [],
},
],
},
{
name: 'Sarah',
children: [],
},
]
},
{
name: 'Tony',
children: [
{
name: 'Lucy',
children: [],
}
]
}
];
function printChildrenNames(children) {
for(var i = 0; i < children.length; i++) {
console.log(children[i].name);
if(children[i].children.length > 0) {
printChildrenNames(children[i].children);
}
}
}
printChildrenNames(products)
Here is an iterative solution using object-scan. For your use case a simple recursive solution might be the best choice, however this solution is very clean and easily adjustable when requirements change.
// const objectScan = require('object-scan');
const data = [{ name: 'Allison', children: [{ name: 'John', children: [{ name: 'Scott', children: [] }] }, { name: 'Sarah', children: [] }] }, { name: 'Tony', children: [{ name: 'Lucy', children: [] }] }];
console.log(objectScan(['**.name'], { rtn: 'value', reverse: false })(data));
// => [ 'Allison', 'John', 'Scott', 'Sarah', 'Tony', 'Lucy' ]
.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
const beers = [
{
id: '100',
name: 'stoneys'
},
{
id: '200',
name: 'budweiser'
},
{
id: '300',
name: 'miller'
},
{
id: '400',
name: 'corona'
}
];
const people = [
{
name: 'steve',
teams: [
{
name: 'pirates',
beers: ['100']
},
{
name: 'penguins',
beers: ['300']
}
]
},
{
name: 'jim',
teams: [
{
name: 'indians',
beers: ['200']
},
{
name: 'blue jackets',
beers: ['100', '400']
}
]
}
];
let newPeople = people.map(fan => {
fan.teams.map(team => {
team.beers.map(beer => beers.filter(brand => brand.id === beer)[0])
});
});
Above is a sample I put together to best demonstrate my question. I am having trouble understanding why nested mapping (.map()) of object arrays is not allowing me to alter the nested data. When I console log results, I am either getting an "[undefined, undefined]' or the unchanged "people" array.
I would like to return the same array as "people" except replace the nested "beers" array (people.teams.beers[]) with corresponding objects from the "beers" array. Example of a successful result below:
{
name: 'steve',
teams: [
{
name: 'pirates',
beers: [
{
id: '100',
name: 'stoneys'
}
]
},
{
name: 'penguins',
beers: [
{
id: '300',
name: 'miller'
}
]
}
]
}
Array.map expects a function which takes single array element as parameter and returns a mapped value. In your case you're not returning any value from mapping functions therefore you're getting undefined twice
const beers = [
{
id: '100',
name: 'stoneys'
},
{
id: '200',
name: 'budweiser'
},
{
id: '300',
name: 'miller'
},
{
id: '400',
name: 'corona'
}
];
const people = [
{
name: 'steve',
teams: [
{
name: 'pirates',
beers: ['100']
},
{
name: 'penguins',
beers: ['300']
}
]
},
{
name: 'jim',
teams: [
{
name: 'indians',
beers: ['200']
},
{
name: 'blue jackets',
beers: ['100', '400']
}
]
}
];
let newPeople = people.map(fan => {
let teams = fan.teams.map(team => {
let beer = team.beers.map(beer => beers.filter(brand => brand.id === beer)[0]);
return { name: team.name, beers: beer }
});
return { name: fan.name, teams: teams }
});
console.log(newPeople);
I want to add the children array to node where id = 52126f7d (or another). How do I do it?
var children = [
{ name: 'great-granchild3',
id: '2a12a10h'
},
{ name: 'great-granchild4',
id: 'bpme7qw0'
}
]
// json tree
var objects = {
name: 'all objects',
id:"2e6ca1c3",
children: [
{
name: 'child',
id: "6c03cfbe",
children: [
{ name: 'grandchild1',
id: "2790f59c"
},
{ name: 'grandchild2',
id: "52126f7d"
},
{ name: 'grandchild3',
id: "b402f14b"
},
{
name: 'grandchild4',
id: "6c03cff0",
children: [
{ name: 'great-grandchild1',
id: "ce90ffa6"
},
{ name: 'great-grandchild2',
id: "52f95f28"
}
]
}
]
},
{
name: 'child2',
id: "7693b310",
children: [
{ name: 'grandchild5',
id: "def86ecc"
},
{ name: 'grandchild6',
id: "6224a8f8"
}
]
}
]
}
to end up with
var objects = {
name: 'all objects',
id:"2e6ca1c3",
children: [
{
name: 'child',
id: "6c03cfbe",
children: [
{ name: 'grandchild1',
id: "2790f59c"
},
{ name: 'grandchild2',
id: "52126f7d",
children = [
{ name: 'great-granchild3',
id: '2a12a10h'
},
{ name: 'great-granchild4',
id: 'bpme7qw0'
}
]
},
{ name: 'grandchild3',
id: "b402f14b"
},
{
name: 'grandchild4',
id: "6c03cff0",
children: [
{ name: 'great-grandchild1',
id: "ce90ffa6"
},
{ name: 'great-grandchild2',
id: "52f95f28"
}
]
}
]
},
{
name: 'child2',
id: "7693b310",
children: [
{ name: 'grandchild5',
id: "def86ecc"
},
{ name: 'grandchild6',
id: "6224a8f8"
}
]
}
]
}
by finding the proper node first.
function getNodeById(id, node){
var reduce = [].reduce;
function runner(result, node){
if(result || !node) return result;
return node.id === id && node || //is this the proper node?
runner(null, node.children) || //process this nodes children
reduce.call(Object(node), runner, result); //maybe this is some ArrayLike Structure
}
return runner(null, node);
}
var target = getNodeById("52126f7d", objects);
target.children = children;
How about:
objects.children[0].children[1].children = children;