How to unwind an Array of Objects in NodeJS? - javascript

I want to unwind an array of objects which have arrays of objects nested. The level of nesting is not defined and is not consistent throughout the array.
Here's my sample data
var data = [{
id: 1,
name: 'Harshal',
subjects: [{
id: 1,
name: 'English',
chapters: [{
id: 1,
name: 'Grammar'
}, {
id: 2,
name: 'Comprehension'
}]
}, {
id: 2,
name: 'Maths',
chapters: [{
id: 1,
name: 'Algebra'
}, {
id: 2,
name: 'Geometry'
}]
}]
}, {
id: 2,
name: 'Pankaj',
subjects: [{
id: 3,
name: 'Marathi',
chapters: [{
id: 1,
name: 'Kavita',
topics: [{
id: 1,
name: 'Topic 1'
}]
}]
}, {
id: 4,
name: 'Hindi',
chapters: [{
id: 1,
name: 'Katha',
topics: [{
id: 2,
name: 'Topic 2'
}, {
id: 3,
name: 'Topic 3'
}]
}]
}]
}];
I want to get an output like this:
var op = [{
id: 1,
name: 'Harshal',
subjects: {
id: 1,
name: 'English',
chapters: {
id: 1,
name: 'Grammar'
}
}
}, {
id: 1,
name: 'Harshal',
subjects: {
id: 1,
name: 'English',
chapters: {
id: 2,
name: 'Comprehension'
}
}
}, {
id: 1,
name: 'Harshal',
subjects: {
id: 2,
name: 'Maths',
chapters: {
id: 1,
name: 'Algebra'
}
}
}, {
id: 1,
name: 'Harshal',
subjects: {
id: 2,
name: 'Maths',
chapters: {
id: 2,
name: 'Geometry'
}
}
}, {
id: 2,
name: 'Pankaj',
subjects: {
id: 3,
name: 'Marathi',
chapters: {
id: 1,
name: 'Kavita',
topics: {
id: 1,
name: 'Topic 1'
}
}
}
}, {
id: 2,
name: 'Pankaj',
subjects: {
id: 4,
name: 'Hindi',
chapters: {
id: 1,
name: 'Katha',
topics: {
id: 2,
name: 'Topic 2'
}
}
}
}, {
id: 2,
name: 'Pankaj',
subjects: {
id: 4,
name: 'Hindi',
chapters: {
id: 1,
name: 'Katha',
topics: {
id: 3,
name: 'Topic 3'
}
}
}
}];
I have tried to work with pull-unwind but I guess there's some issues with it. If anyone has any other ideas, I'm open to implement those.

Have you tried recursion?
var data = [{
id: 1,
name: 'Harshal',
subjects: [{
id: 1,
name: 'English',
chapters: [{
id: 1,
name: 'Grammar'
}, {
id: 2,
name: 'Comprehension'
}]
}, {
id: 2,
name: 'Maths',
chapters: [{
id: 1,
name: 'Algebra'
}, {
id: 2,
name: 'Geometry'
}]
}]
}, {
id: 2,
name: 'Pankaj',
subjects: [{
id: 3,
name: 'Marathi',
chapters: [{
id: 1,
name: 'Kavita',
topics: [{
id: 1,
name: 'Topic 1'
}]
}]
}, {
id: 4,
name: 'Hindi',
chapters: [{
id: 1,
name: 'Katha',
topics: [{
id: 2,
name: 'Topic 2'
}, {
id: 3,
name: 'Topic 3'
}]
}]
}]
}];
function unravel(obj)
{
var out = [];
var added = false;
for(var i in obj) {
if(obj[i] instanceof Array) {
for(var j in obj[i]) {
var r = unravel(obj[i][j]);
for(var k in r) {
var a = {};
for(var key in obj) { // make copy of obj
a[key] = obj[key];
}
a[i] = r[k];
added = true;
out.push(a);
}
}
}
}
if(!added) {
out.push(obj);
}
return out;
}
var op = [];
for(var i in data)
op = op.concat(unravel(data[i]));
console.log(JSON.stringify(op, null, 4));

Related

Need to filter a object using JavaScript

I have a object
course = [
{
id: 1,
name: 'Computer Science',
country: 'Uinited State',
university:{
id: 1,
name: 'Oxford'
}
},
{
id: 2,
name: 'BBA',
country: 'Uinited State',
university:{
id: 2,
name: 'Starnford'
}
},
{
id: 3,
name: 'BBA',
country: 'Uinited State',
university:{
id: 1,
name: 'Oxford'
}
},
{
id: 4,
name: 'Computer Engineering',
country: 'Uinited State',
university:{
id: 1,
name: 'Oxford'
}
},
{
id: 5,
name: 'MBA',
country: 'Uinited State',
university:{
id: 2,
name: 'Starnford'
}
},
{
id: 6,
name: 'ETE',
country: 'Uinited State',
university:{
id: 1,
name: 'Oxford'
}
}
]
I need to filter this object. I need to filter by university and the filter university can not be 3 length.
format like below.
filterData = [
{
uniVersityId: 1,
data: [
{
id: 1,
name: 'Computer Science',
country: 'Uinited State',
university:{
id: 1,
name: 'Oxford'
},
},
{
id: 3,
name: 'BBA',
country: 'Uinited State',
university:{
id: 1,
name: 'Oxford'
}
},
{
id: 4,
name: 'Computer Engineering',
country: 'Uinited State',
university:{
id: 1,
name: 'Oxford'
}
},
],
},
{
uniVersityId: 2,
data: [{
id: 2,
name: 'BBA',
country: 'Uinited State',
university:{
id: 2,
name: 'Starnford'
}
},
{
id: 5,
name: 'MBA',
country: 'Uinited State',
university:{
id: 1,
name: 'Starnford'
}
},
],
}
I have started
course.map(course=>{
if( !mainData.length ){
mainData.country.name.push(course)
}
})
Need to filter the array by university. university will be a array and the university array length can not be 3. if there have more than 3 data ignore.
Its not so much a filter you need, its really grouping by university name, and ensuring there is a maximum of 3 items in each group
const course=[{id:1,name:"Computer Science",country:"Uinited State",university:{id:1,name:"Oxford"}},{id:2,name:"BBA",country:"Uinited State",university:{id:2,name:"Starnford"}},{id:3,name:"BBA",country:"Uinited State",university:{id:1,name:"Oxford"}},{id:4,name:"Computer Engineering",country:"Uinited State",university:{id:1,name:"Oxford"}},{id:5,name:"MBA",country:"Uinited State",university:{id:2,name:"Starnford"}},{id:6,name:"ETE",country:"Uinited State",university:{id:1,name:"Oxford"}}];
const result = Object.entries(course.reduce( (acc,i) => {
acc[i.university.id] = acc[i.university.id] || [];
if(acc[i.university.id].length < 3){
acc[i.university.id].push(i);
}
return acc;
},{})).map ( ([universityId,data]) => ({universityId, data}))
console.log(result);
var val = 'Oxford';
var temp= this.temp.filter((d) => {
return d.university.name.toLowerCase().indexOf(val) !== -1 || !val
});

find method not returning '0th' matched object react, or react-native or javascript

Not getting all matched objects, its is returning all objects except '{ ID:0, Name: 'General Group' }', i want all matched objects
let arrDashboardIconGroups = [
{ ID:0, Name: 'General Group' },
{ ID: 1, Name: 'Patient Administration' },
{ ID: 2, Name: 'Medical Charts' },
{ ID: 3, Name: 'Medical Procedures' },
{ ID: 13, Name: 'Purchase' },
{ ID: 14, Name: 'Sales' },
{ ID: 5, Name: 'Insurance' },
{ ID: 4, Name: 'Cash' },
{ ID: 6, Name: 'Pharmacy' },
{ ID: 7, Name: 'Inventory' },
{ ID: 8, Name: 'Lab' },
{ ID: 9, Name: 'Imaging' },
{ ID: 10, Name: 'In Patient' },
{ ID: 11, Name: 'System Administration' },
{ ID: 12, Name: 'Accounting' }
]
const getMatchedobjects=()=> {
let result = [0,1,2,3,4,]
let matchedArray = arrDashboardIconGroups.filter(val =>result.find(
(items)=>items == val.ID))
console.log(matchedArray)
}
getMatchedobjects()
You are returning the value of
result.find((items) => items == val.ID)
In the first case, the value returned is 0 which is a falsy value. So It won't include in the final filter result.
You can run the below code and see the returning values.
let arrDashboardIconGroups = [
{ ID: 0, Name: "General Group" },
{ ID: 1, Name: "Patient Administration" },
{ ID: 2, Name: "Medical Charts" },
{ ID: 3, Name: "Medical Procedures" },
{ ID: 13, Name: "Purchase" },
{ ID: 14, Name: "Sales" },
{ ID: 5, Name: "Insurance" },
{ ID: 4, Name: "Cash" },
{ ID: 6, Name: "Pharmacy" },
{ ID: 7, Name: "Inventory" },
{ ID: 8, Name: "Lab" },
{ ID: 9, Name: "Imaging" },
{ ID: 10, Name: "In Patient" },
{ ID: 11, Name: "System Administration" },
{ ID: 12, Name: "Accounting" },
];
const getMatchedobjects = () => {
let result = [0, 1, 2, 3, 4];
let matchedArray = arrDashboardIconGroups.filter((val) => {
const returnResult = result.find((items) => items == val.ID);
console.log(returnResult);
return returnResult;
// result.includes(val.ID)
});
console.log(matchedArray);
};
getMatchedobjects();
Alternatively, you can use includes
let arrDashboardIconGroups = [
{ ID: 0, Name: "General Group" },
{ ID: 1, Name: "Patient Administration" },
{ ID: 2, Name: "Medical Charts" },
{ ID: 3, Name: "Medical Procedures" },
{ ID: 13, Name: "Purchase" },
{ ID: 14, Name: "Sales" },
{ ID: 5, Name: "Insurance" },
{ ID: 4, Name: "Cash" },
{ ID: 6, Name: "Pharmacy" },
{ ID: 7, Name: "Inventory" },
{ ID: 8, Name: "Lab" },
{ ID: 9, Name: "Imaging" },
{ ID: 10, Name: "In Patient" },
{ ID: 11, Name: "System Administration" },
{ ID: 12, Name: "Accounting" },
];
const getMatchedobjects = () => {
let result = [0, 1, 2, 3, 4];
let matchedArray = arrDashboardIconGroups.filter((val) => result.includes(val.ID));
console.log(matchedArray);
};
getMatchedobjects();
Issue
Find returns a value/object (the first matching), but it seems you want to filter the arrDashboardIconGroups array by those that match an id specified in the result array. When result[0] is returned, 0 is the value, which is falsey, and the filter doesn't return the element from the arrDashboardIconGroups array.
Solution
Use Array.prototype.some to return the boolean that filter needs to include an element in the result array.
let arrDashboardIconGroups = [
{ ID:0, Name: 'General Group' },
{ ID: 1, Name: 'Patient Administration' },
{ ID: 2, Name: 'Medical Charts' },
{ ID: 3, Name: 'Medical Procedures' },
{ ID: 13, Name: 'Purchase' },
{ ID: 14, Name: 'Sales' },
{ ID: 5, Name: 'Insurance' },
{ ID: 4, Name: 'Cash' },
{ ID: 6, Name: 'Pharmacy' },
{ ID: 7, Name: 'Inventory' },
{ ID: 8, Name: 'Lab' },
{ ID: 9, Name: 'Imaging' },
{ ID: 10, Name: 'In Patient' },
{ ID: 11, Name: 'System Administration' },
{ ID: 12, Name: 'Accounting' }
];
const getMatchedobjects = () => {
let result = [0,1,2,3,4,];
let matchedArray = arrDashboardIconGroups.filter(val => result.some((items)=>items == val.ID));
console.log(matchedArray);
}
getMatchedobjects();
Alternatively you could also check that result array includes the matching id.
let arrDashboardIconGroups = [
{ ID:0, Name: 'General Group' },
{ ID: 1, Name: 'Patient Administration' },
{ ID: 2, Name: 'Medical Charts' },
{ ID: 3, Name: 'Medical Procedures' },
{ ID: 13, Name: 'Purchase' },
{ ID: 14, Name: 'Sales' },
{ ID: 5, Name: 'Insurance' },
{ ID: 4, Name: 'Cash' },
{ ID: 6, Name: 'Pharmacy' },
{ ID: 7, Name: 'Inventory' },
{ ID: 8, Name: 'Lab' },
{ ID: 9, Name: 'Imaging' },
{ ID: 10, Name: 'In Patient' },
{ ID: 11, Name: 'System Administration' },
{ ID: 12, Name: 'Accounting' }
];
const getMatchedobjects=()=> {
let result = [0,1,2,3,4,];
let matchedArray = arrDashboardIconGroups.filter(val => result.includes(val.ID)) ;
console.log(matchedArray);
}
getMatchedobjects();
find() returns value of the first element in the provided array that satisfies the provided testing function. Since 0 is a falsy value, it does not include it in the final array. See MDN Docs
You can map the result array, and use arrDashboardIconGroups's find function, and return the matching objects.
let arrDashboardIconGroups = [
{ ID: 0, Name: 'General Group' },
{ ID: 1, Name: 'Patient Administration' },
{ ID: 2, Name: 'Medical Charts' },
{ ID: 3, Name: 'Medical Procedures' },
{ ID: 13, Name: 'Purchase' },
{ ID: 14, Name: 'Sales' },
{ ID: 5, Name: 'Insurance' },
{ ID: 4, Name: 'Cash' },
{ ID: 6, Name: 'Pharmacy' },
{ ID: 7, Name: 'Inventory' },
{ ID: 8, Name: 'Lab' },
{ ID: 9, Name: 'Imaging' },
{ ID: 10, Name: 'In Patient' },
{ ID: 11, Name: 'System Administration' },
{ ID: 12, Name: 'Accounting' }
]
const getMatchedobjects=()=> {
let result = [0, 1,2,3,4,99] //99 for trial
let matchedArray = result.map((res)=>arrDashboardIconGroups.find((val)=>val.ID == res)).filter(Boolean);
console.log(matchedArray)
}
getMatchedobjects()

How to get list of parents id in json object

My nested json array looks like:
[
{
id: 1,
name: "Mike",
children: [
{ id: 2, name: "MikeC1" },
{ id: 3, name: "MikeC2" },
{
id: 4, name: "MikeC3",
children: [{ id: 5, name: "MikeCC1" }]
},
]
},
{
id: 6,
name: "Json",
children: [
{ id: 7, name: "JsonC1" },
{ id: 8, name: "JsonC2" },
{
id: 9, name: "JsonC3",
children: [{ id: 10, name: "JsonCC1" },{ id: 11, name: "JsonCC2" }]
},
]
}
]
Now I get a id like "11"
then get the parent ids array in json like [6,9,11]
How to do?
var id = 11
console.log(findParent(id))
//result is [6,9,11]
You need to do recursive search
const persons = [
{
id: 1,
name: "Mike",
children: [
{ id: 2, name: "MikeC1" },
{ id: 3, name: "MikeC2" },
{
id: 4, name: "MikeC3",
children: [{ id: 5, name: "MikeCC1" }]
},
]
},
{
id: 6,
name: "Json",
children: [
{ id: 7, name: "JsonC1" },
{ id: 8, name: "JsonC2" },
{
id: 9, name: "JsonC3",
children: [{ id: 10, name: "JsonCC1" },{ id: 11, name: "JsonCC2" }]
},
]
}
];
function searchRecursive(items, id) {
const allIds = [];
items.forEach(item => {
if(item.id === id) {
allIds.push(item.id);
}
else if(item.children) {
const ids = searchRecursive(item.children, id);
if(ids.length) allIds.push(item.id);
ids.forEach(id => allIds.push(id));
}
});
return allIds;
}
console.log(searchRecursive(persons, 11));

How to flatten the nested Array?

How do I flatten the nested Array in the Array?
Here is the example input Array,
const input = [
{
id: 1,
name: 'Charles',
otherFields: [{
id: 2,
name: 'Pung',
}, {
id: 3,
name: 'James',
}]
}, {
id: 4,
name: 'Charles',
otherFields: [{
id: 5,
name: 'Pung',
}, {
id: 6,
name: 'James',
}]
}
]
Output Array I want to get.
[{
id: 1,
name: 'Charles'
}, {
id: 2,
name: 'Pung',
}, {
id: 3,
name: 'James',
}, {
id: 4,
name: 'Charles'
}, {
id: 5,
name: 'Pung',
}, {
id: 6,
name: 'James',
}]
I want to somehow get the output in one statement like
input.map((sth) => ({...sth??, sth.field...})); // I'm not sure :(
With flatMap you can take out the otherFields property, and returning an array containing the parent item and the other array:
const input = [{
id: 1,
name: 'Charles',
otherFields: [{
id: 2,
name: 'Pung',
}, {
id: 3,
name: 'James',
}]
}];
console.log(
input.flatMap(({ otherFields, ...item }) => [item, ...otherFields])
);
For more than one level, you could take a recursive approach of flattening.
const
flat = ({ otherFields = [], ...o }) => [o, ...otherFields.flatMap(flat)],
input = [{ id: 1, name: 'Charles', otherFields: [{ id: 2, name: 'Pung' }, { id: 3, name: 'James', otherFields: [{ id: 4, name: 'Jane' }] }] }],
result = input.flatMap(flat);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Combine two different sized array of objects in javascript [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I have two different sized arrays like this
[{ id: 1, name: 'One', contacts: [] },
{ id: 2, name: 'Two', contacts: [] },
{ id: 3, name: 'Three', contacts: [] },
{ id: 4, name: 'Four', contacts: [] }]
[{ id: 1, name: 'One', contacts: [{ id: 100, name: "C1" }, { id: 101, name: "C2" }] },
{ id: 3, name: 'Three', contacts: [{ id: 120, name: "C1" }, { id: 121, name: "C2" }] },
{ id: 5, name: 'Five', contacts: [{ id: 420, name: "F1" }, { id: 421, name: "F2" }] }];
I tried with below code in javascript
const mergeArray = (source, merge, by) => source.map(item => ({
...item,
...(merge.find(i => i[by] === item[by]) || {}),
}));
output = mergeArray(this.oldArray1,this.oldArray2,'id');
It gives output as
[{ id: 1, name: 'One', contacts: [{ id: 100, name: "C1" }, { id: 101, name: "C2" }] },
{ id: 2, name: 'Two', contacts: [] }
{ id: 3, name: 'Three', contacts: [{ id: 120, name: "C1" }, { id: 121, name: "C2" }] }]
But desired output like this
[{ id: 1, name: 'One', contacts: [{ id: 100, name: "C1" }, { id: 101, name: "C2" }] },
{ id: 2, name: 'Two', contacts: [] }
{ id: 3, name: 'Three', contacts: [{ id: 120, name: "C1" }, { id: 121, name: "C2" }] },
{ id: 4, name: 'Four', contacts: [] }
{ id: 5, name: 'Five', contacts: [{ id: 420, name: "F1" }, { id: 421, name: "F2" }] }]
you could collect the arrays in an array, or simply concat the arrays and then reduce this array by checkin if the id is in the result array. If not add the object to the result array or if exist, then extend contacts with the acutal data.
var array1 = [{ id: 1, name: 'One', contacts: [] }, { id: 2, name: 'Two', contacts: [] }, { id: 3, name: 'Three', contacts: [] }, { id: 4, name: 'Four', contacts: [] }],
array2 = [{ id: 1, name: 'One', contacts: [{ id: 100, name: "C1" }, { id: 101, name: "C2" }] }, { id: 3, name: 'Three', contacts: [{ id: 120, name: "C1" }, { id: 121, name: "C2" }] }, { id: 5, name: 'Five', contacts: [{ id: 420, name: "F1" }, { id: 421, name: "F2" }] }],
merged = [array1, array2].reduce((r, a) => {
a.forEach(o => {
var object = r.find(({ id }) => id === o.id);
if (!object) {
return r.push(o);
}
object.contacts.push(...o.contacts);
});
return r;
}, []);
console.log(merged);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Categories

Resources