search an item in multidimentionnal array - javascript

I'm trying to find an element on a multidimentionnal array usin JAVASCRIPT function, but I get error
This is my array's data:
export const datas = [
{
id: 1,
firstName: 'John',
tables: [
{ ID: 11, title: 'Lorem' },
{ ID: 12, title: 'Ipsum' },
],
},
{
id: 2,
firstName: 'Doe',
tables: [
{
ID: 22,
title: 'Arke',
nodes: [{ name: 'Name1' }, { name: 'Name2' }, { name: 'Name3' }],
},
{ ID: 23, title: 'Korem' },
],
},
{
id: 3,
firstName: 'Brad',
tables: [
{
ID: 30,
title: 'Mern',
nodes: [{ name: 'Name4' }, { name: 'Name5' }, { name: 'Name6' }],
},
{
ID: 31,
title: 'Full',
nodes: [{ name: 'Name7' }, { name: 'Name8' }, { name: 'Name9' }],
},
],
},
];
I've tried a reccursive function but it's not work, this is my code :
export const findById = (arr, id) => {
for (let o of arr) {
if (o.tables.length > 0) {
let a = findById(o.tables.nodes, 'id');
console.log(a);
}
}
};
I want to print the Object with ID 22, the problem is that I don't have the same structure in each dimension, and it still confuse me..
My Input : 22
My output :
{
ID: 22,
title: 'Arke',
nodes: [{ name: 'Name1' }, { name: 'Name2' }, { name: 'Name3' }],
},
Have you an idea how to edit my function to get my input's response ?

Your recursive function wasn't too far off, you need to check if the item as a tables first before recursively calling it again. And then finally just check the ID in the loop.
eg..
const datas=[{id:1,firstName:"John",tables:[{ID:11,title:"Lorem"},{ID:12,title:"Ipsum"}]},{id:2,firstName:"Doe",tables:[{ID:22,title:"Arke",nodes:[{name:"Name1"},{name:"Name2"},{name:"Name3"}]},{ID:23,title:"Korem"}]},{id:3,firstName:"Brad",tables:[{ID:30,title:"Mern",nodes:[{name:"Name4"},{name:"Name5"},{name:"Name6"}]},{ID:31,title:"Full",nodes:[{name:"Name7"},{name:"Name8"},{name:"Name9"}]}]}];
function findById(arr, ID) {
for (const a of arr) {
if (a.tables) {
const r = findById(a.tables, ID);
if (r) return r;
}
if (a.ID === ID) return a;
}
}
console.log(findById(datas, 22));

if you just need the nested data you can use flatMap and find
const findById = (arr, id) =>
arr
.flatMap(d => d.tables)
.find(t => t.ID === id)
const datas = [{
id: 1,
firstName: 'John',
tables: [{
ID: 11,
title: 'Lorem'
},
{
ID: 12,
title: 'Ipsum'
},
],
},
{
id: 2,
firstName: 'Doe',
tables: [{
ID: 22,
title: 'Arke',
nodes: [{
name: 'Name1'
}, {
name: 'Name2'
}, {
name: 'Name3'
}],
},
{
ID: 23,
title: 'Korem'
},
],
},
{
id: 3,
firstName: 'Brad',
tables: [{
ID: 30,
title: 'Mern',
nodes: [{
name: 'Name4'
}, {
name: 'Name5'
}, {
name: 'Name6'
}],
},
{
ID: 31,
title: 'Full',
nodes: [{
name: 'Name7'
}, {
name: 'Name8'
}, {
name: 'Name9'
}],
},
],
},
];
console.log(findById(datas, 22))

js has amazing array options https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
the ones which will help you most are probably:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap
here are some examples
// get the base with id 22
const baseWith22ID = datas.filter(f => f.tables.filter(s => s.id = 22))
// (i guess you want this one) get all elements with id 22
const onlyElementsWith22ID = datas.flatMap(f => f.tables.filter(s => s.id = 22))

Related

How to enumare objects and total of them with the same key with another object in array js

I'm populing a pdf template with an array of employees, and now I need to count the number of employees working in a same department, I found a way to count the total of concurrences but I can't enumarate the employee working in the department and the total of them. Can you help me? Thanks!!!
For example, I have this array of objects
const employees = [
{
id: 1,
name: "john",
department: {
id: 1,
},
},
{
id: 1,
name: "Mike",
department: {
id: 3,
},
},
{
id: 1,
name: "Leona",
department: {
id: 1,
},
},
{
id: 1,
name: "Lara",
department: {
id: 1,
},
},
];
Result Expected:
const employees = [
{
id: 1,
name: "john",
department: {
id: 1,
},
totalForDeparments: "1/3",
},
{
id: 1,
name: "Mike",
department: {
id: 3,
},
totalForDeparments: "1/1",
},
{
id: 1,
name: "Leona",
department: {
id: 1,
},
totalForDeparments: "2/3",
},
{
id: 1,
name: "Lara",
department: {
id: 1,
},
totalForDeparments: "3/3",
},
];
First you group by the department.id - then you can iterate the original array adding the correct indexes.
const employees = [{id:1,name:"john",department:{id:1}},{id:1,name:"Mike",department:{id:3}},{id:1,name:"Leona",department:{id:1}},{id:1,name:"Lara",department:{id:1}},];
var grouped = employees.reduce(function(agg, item) {
agg[item.department.id] = agg[item.department.id] || {
count: 0,
current: 0
}
agg[item.department.id].count++;
return agg;
}, {});
employees.map(function(item) {
var data = grouped[item.department.id]
data.current++;
item.totalForDeparments = data.current + "/" + data.count
})
console.log(employees)
.as-console-wrapper {max-height: 100% !important}

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));

Updating objects of array in array with array of Object

I have a two javaScript Array
let x = [
{
id: 'Abc',
children: [
{
id: 12,
name: 'john'
}, {
id: 13,
name: 'dow'
}
]
}, {
id: 'xyz',
children: [
{
id: 123,
name: 'jack'
}, {
id: 134,
name: 'abc'
}
]
}
]
let y = [
{
id: 12,
name: 'mac'
}, {
id: 13,
name: 'dow'
}, {
id: 123,
name: 'Tom'
}, {
id: 134,
name: 'abc'
}
]
I want to update my x with y having updated array like this
[
{
id: 'Abc',
children: [
{
id: 12,
name: 'mac'
}, {
id: 13,
name: 'dow'
}
]
}, {
id: 'xyz',
children: [
{
id: 123,
name: 'Tom'
}, {
id: 134,
name: 'abc'
}
]
}
]
I tried this solution like this
x.map((a, index)=>{
a.children.map((b, i)=>{
// console.log('update')
y.find(o => o.id === b.id) || b;
})
})
but I am having undefined. I searched many answer but didn't get any luck.
x.map((a, index)=>{
a.children.map((b, i)=>{
// console.log('update')
y.find(o => o.id === b.id) || b;
})
})
First of all, you're making a common mistake while using an array function:
Brackets {} are optional for one-line instructions, but then you need to specify the return keyword.
arr.filter(v => v === 2) is equivalent to arr.filter(v => {return v === 2}). Forget return, and filter() will return an empty array.
One-line solution :
const res = x.map((a, index) => ({ ...a, children: a.children.map((b, i) => y.find(o => o.id === b.id) || b) }));
Code snippet :
let x = [
{
id: 'Abc',
children: [
{
id: 12,
name: 'john'
}, {
id: 13,
name: 'dow'
}
]
}, {
id: 'xyz',
children: [
{
id: 123,
name: 'jack'
}, {
id: 134,
name: 'abc'
}
]
}
]
let y = [
{
id: 12,
name: 'mac'
}, {
id: 13,
name: 'dow'
}, {
id: 123,
name: 'Tom'
}, {
id: 134,
name: 'abc'
}
]
const res = x.map((a, index) =>
({ ...a, children: a.children.map((b, i) => y.find(o => o.id === b.id) || b) }));
console.log(res);
First make loopup object for y, then use map for children for x
let x = [
{
id: "Abc",
children: [
{
id: 12,
name: "john",
},
{
id: 13,
name: "dow",
},
],
},
{
id: "xyz",
children: [
{
id: 123,
name: "jack",
},
{
id: 134,
name: "abc",
},
],
},
];
let y = [
{
id: 12,
name: "mac",
},
{
id: 13,
name: "dow",
},
{
id: 123,
name: "Tom",
},
{
id: 134,
name: "abc",
},
];
const lookupY = {};
y.forEach(({ id, name }) => (lookupY[id] = name));
const newX = x.map(({ id, children }) => ({
id,
children: children.map((item) => ({ id:item.id, name: lookupY[item.id] })),
}));
console.log(newX)
First of all you forgot to return the result inside callback function. Then you should not lose others keys of object.
const x = [
{
id: 'Abc',
children: [
{
id: 12,
name: 'john'
}, {
id: 13,
name: 'dow'
}
]
}, {
id: 'xyz',
children: [
{
id: 123,
name: 'jack'
}, {
id: 134,
name: 'abc'
}
]
}
];
const y = [
{
id: 12,
name: 'mac'
}, {
id: 13,
name: 'dow'
}, {
id: 123,
name: 'Tom'
}, {
id: 134,
name: 'abc'
}
];
const newArr = x.map((a, index) => {
const children = a.children.map((b, i) => {
return y.find(o => o.id === b.id) || b;
})
return { ...a, children };
})
console.log(newArr);

How to add object element in array based on condition

I have static array constant of objects something similar to below.
export const EMPLOYEES = [
{
id: 2,
name: ‘John’,
},
{
id: 3,
name: ‘Doe’,
},
{
id: 4,
name: ‘Bull’,
},
{
id: 5,
name: ‘Scott’,
},
];
Now I need to add the last element only based on if some condition is true. Some this like if isAmerican() is true.
Can somebody help me here how to add element based on the condition? Thanks.
You can do it using spread operator:
export const EMPLOYEES = [
{
id: 2,
name: "John",
},
{
id: 3,
name: "Doe",
},
{
id: 4,
name: "Bull",
},
{
id: 5,
name: "Scott",
},
... isAmerican() ? [{ id: 6, name: "Jemmy"}] : []
];
You should never modify (or try to modify) a constant. I can see two ways you can do this:
Create a pure function to return a new constant with the new object added to the array
Use a spread operator in the definition of the constant
Option 1: Pure function
function makeNewArray(array, objectToAppend, isAmerican) {
return isAmerican ? [...array, objectToAppend] : array
}
const EMPLOYEES = [
{
id: 2,
name: "John",
},
{
id: 3,
name: "Doe",
},
{
id: 4,
name: "Bull",
},
{
id: 5,
name: "Scott",
}
];
const arrayWithAmerican = makeNewArray(EMPLOYEES, { id: 6, name: "American Frank"}, true);
const arrayWithoutAmerican = makeNewArray(EMPLOYEES, { id: 6, name: "Not American Frank"}, false);
console.log(arrayWithAmerican);
console.log(arrayWithoutAmerican);
Option 2: Spread operator
function isAmerican(){
// generic code here.
return true;
}
const EMPLOYEES = [
{
id: 2,
name: "John",
},
{
id: 3,
name: "Doe",
},
{
id: 4,
name: "Bull",
},
{
id: 5,
name: "Scott",
},
... isAmerican() ? [{ id: 6, name: "American Frank"}] : []
];
If the condition will be fulfilled, simply push an object to your EMPLOYEES array:
let isAmerican = true;
const EMPLOYEES = [
{
id: 2,
name: "John",
},
{
id: 3,
name: "Doe",
},
{
id: 4,
name: "Bull",
},
{
id: 5,
name: "Scott",
},
];
if(isAmerican) {
EMPLOYEES.push({
id: 6,
name: "Frank"
})
}
console.log(EMPLOYEES)
Fiddle: https://jsfiddle.net/rqx35pLz/

Return a set of documents with all sub-arrays containing a given value in loopback or nodejs

How do I return a set of documents that has sub-arrays that matches common values. To better explain, consider the following data:
[
{
Category: 1,
Products: [
{
Name: 'ABC',
ColorCode:[1,2,3,4,5]
},
{
Name: 'DEF',
ColorCode:[1,2,3,4,5,6]
},
{
Name: 'GHI',
ColorCode:[1,2,3,4,6,7]
}
]
},
{
Category: 2,
Products: [
{
Name: 'JKL',
ColorCode:[4,6,7,]
},
{
Name: 'MNO',
ColorCode:[4,5,6,9,]
}
]
},
{
Category: 3,
Products: [
{
Name: 'OPQ',
ColorCode:[3,4,5,6,9,10]
},
{
Name: 'RST',
ColorCode:[2,3,5,6,9,10]
}
]
}]
The task is,
Get all the Categories with all the products containing a specific color code:
For example,
For ColorCode = 6,
Result should be:
[
{
Category: 2,
Products: [
{
Name: 'JKL',
ColorCode:[4,6,7,]
},
{
Name: 'MNO',
ColorCode:[5,6,9,]
}
]
},
{
Category: 3,
Products: [
{
Name: 'OPQ',
ColorCode:[3,4,5,6,9,10]
},
{
Name: 'RST',
ColorCode:[2,3,5,6,9,10]
}
]
}]
For ColorCode = 4,
Result should be:
[
{
Category: 1,
Products: [
{
Name: 'ABC',
ColorCode:[1,2,3,4,5]
},
{
Name: 'DEF',
ColorCode:[1,2,3,4,5,6]
},
{
Name: 'GHI',
ColorCode:[1,2,3,4,6,7]
}
]
},
{
Category: 2,
Products: [
{
Name: 'JKL',
ColorCode:[4,6,7,]
},
{
Name: 'MNO',
ColorCode:[4,5,6,9,]
}
]
}]
For ColorCode = 7,
Result should be an empty array:
[]
Thanks in advance.
You're looking for Array.prototype.filter.
// filter out categories that don't contain color code 4
categories.filter(function(category) {
return category.products.filter(containsColor(4)) > 0;
});
function containsColor(colorCode) {
return function(product) {
return product.ColorCode.indexOf(colorCode) >= 0;
};
}

Categories

Resources