arr1 = [
{
name: "will",
value: "1"
},
{
name: "nelson",
value: "3"
}
];
and
arr2 = [
{
name: "will",
value: 1,
submenu: [
{
name: "ralph",
value: 2
}
]
}
]
then remove ralph from the second array. i already created a function who do it but just check the first element and not verify the submenu.
comparador(arrSecundario) {
return (arrAtual) => {
return arrSecundario.filter(function (other) {
return other.value === arrAtual.value;
}).length !== 0;
};
}
this.arr2.filter(this.comparador(this.arr1));
Need to map array after filter. You can do like this and can also add "prop === 'submenu'" for specifically checking submenu inner array only.
var arr1 = [
{
name: "will",
value: "1"
},
{
name: "nelson",
value: "3"
}
];
var arr2 = [
{
name: "will",
value: 1,
submenu: [
{
name: "ralph",
value: 2
},
// {
// name: "nelson",
// value: 3
// }
]
}
];
function filterComparador(arrSecundario) {
return (arrAtual) => {
return arrSecundario.filter((other) => {
return other.value == arrAtual.value;
}).length != 0;
};
}
function mapComparador(arrSecundario) {
return (arrAtual) => {
Object.keys(arrAtual).forEach((prop) => {
if (Array.isArray(arrAtual[prop])) {
let propValue = arrAtual[prop].filter(this.filterComparador(arrSecundario));
if (propValue.length > 0) {
arrAtual[prop] = propValue.map(this.mapComparador(this.arrSecundario));
} else {
delete arrAtual[prop];
}
}
});
return arrAtual;
};
}
var manipulatedArray = this.arr2.filter(this.filterComparador(this.arr1))
.map(this.mapComparador(this.arr1));
console.log(manipulatedArray);
Related
How do I reach isBoatOwner so I can return it's value in a array?
My code is returning undefined.
pluck(
[
{ name: "Tim", isBoatOwner: true },
{ name: "Matt", isBoatOwner: false },
{ name: "Elie" }
],
"isBoatOwner"
);
function pluck(defObj, key) {
let arr = [];
for (let i = 0; i < defObj.length; i++) {
if (Object.keys(defObj[i]) == key) {
arr.push(defObj[i][key]);
} else {
arr.push(undefined);
}
}
return arr.flat();
}
All you need is a simple .map():
console.log(pluck(
[
{ name: "Tim", isBoatOwner: true },
{ name: "Matt", isBoatOwner: false },
{ name: "Elie" }
],
"isBoatOwner"
));
function pluck(defObj, key) {
return defObj.map(function (obj) {
return obj[key];
});
}
So the above function collects all the values of isBoatOwner from the array and sends it as an array of values.
[
true,
false,
undefined
]
In your code you are trying to compare an array to a string to see if the property exists. That is never going to match
function pluck(defObj, key) {
let arr = [];
for (let i = 0; i < defObj.length; i++) {
// if (Object.keys(defObj[i]) == key) {
if (defObj[i][key] !== undefined) {
arr.push(defObj[i][key]);
} else {
arr.push(undefined);
}
}
return arr.flat();
}
var result = pluck(
[{
name: "Tim",
isBoatOwner: true
},
{
name: "Matt",
isBoatOwner: false
},
{
name: "Elie"
}
],
"isBoatOwner"
);
console.log(result);
But the check does not make too much sense since you are pushing undefined into it. So it could just be
function pluck(defObj, key) {
let arr = [];
for (let i = 0; i < defObj.length; i++) {
arr.push(defObj[i][key]);
}
return arr.flat();
}
var result = pluck(
[{
name: "Tim",
isBoatOwner: true
},
{
name: "Matt",
isBoatOwner: false
},
{
name: "Elie"
}
],
"isBoatOwner"
);
console.log(result);
Modern approach is just map
function pluck(defObj, key) {
// return defObj.map(function(item) { return item[key]; });
return defObj.map(item => item[key]);
}
var result = pluck(
[{
name: "Tim",
isBoatOwner: true
},
{
name: "Matt",
isBoatOwner: false
},
{
name: "Elie"
}
],
"isBoatOwner"
);
console.log(result);
let tree = {
name: "A",
children: [
{
name: 'A-1',
children: [
{name: "A-1-A"},
{name: "A-1-B"},
]
},
{
name: 'B-1',
children: [
{
name: "B-1-A",
children: [
{name: "B-11-A"},
{name: "B-11-B"}
]
},
{name: "B-1-B"},
]
},
]
};
I am trying to find object from tree object using recursion .
when I call like this searchFn(tree,'A-1') it should return {
name: 'A-1',
children: [
{name: "A-1-A"},
{name: "A-1-B"},
]
} object
it I call like this searchFn(tree,'A-1-A') it should return this
{name: "A-1-A"}
I tried like this but not working
function searchFn(obj ,searchText){
if(obj.name === searchText) return obj
if(obj.children.length > 0){
return searchFn(obj.children.pop(),searchText)
}
return null
}
You need to iterate the children of the object and take a variable for the result.
function searchFn(object, searchText) {
var result;
if (object.name === searchText) return object;
(object.children || []).some(o => result = searchFn(o, searchText));
return result || null;
}
let tree = { name: "A", children: [{ name: 'A-1', children: [{ name: "A-1-A" }, { name: "A-1-B" }] }, { name: 'B-1', children: [{ name: "B-1-A", children: [{ name: "B-11-A" }, { name: "B-11-B" }] }, { name: "B-1-B" }] }] };
console.log(searchFn(tree, 'foo'));
console.log(searchFn(tree, 'A-1'));
.as-console-wrapper { max-height: 100% !important; top: 0; }
First, you should create a class for readability. Then you should have a loop inside the function that iterates over the children and only returns if a child is found.
class Node {
static fromStruct = (struct) => {
const tree = new Node(struct.name);
if(!struct.children) return tree;
for(const child of struct.children) {
tree.children.push(Node.fromStruct(child));
}
return tree;
}
constructor(name){
this.name = name;
this.children = [];
}
addChild = (parentName, childName) => {
const parent = this.searchFn(parentName);
if(!parent) throw new Error("Parent not found");
parent.children.push(new Node(childName));
}
searchFn = (name) => {
if(this.name === name) return this;
for(const child of this.children) {
const found = child.searchFn(name);
if(found !== null) return found;
}
return null;
}
}
const data = {
name: "A",
children: [
{
name: 'A-1',
children: [
{name: "A-1-A"},
{name: "A-1-B"},
]
},
{
name: 'B-1',
children: [
{
name: "B-1-A",
children: [
{name: "B-11-A"},
{name: "B-11-B"}
]
},
{name: "B-1-B"},
]
},
]
};
const tree = Node.fromStruct(data);
console.log(tree.searchFn("A-1-A"));
const tree = {"name":"A","children":[{"name":"A-1","children":[{"name":"A-1-A"},{"name":"A-1-B"}]},{"name":"B-1","children":[{"name":"B-1-A","children":[{"name":"B-11-A"},{"name":"B-11-B"}]},{"name":"B-1-B"}]}]}
const searchFn = (tree, name) => {
let result = null;
if (typeof tree !== "object") return result;
if (tree.name === name) return tree;
if (tree.children && tree.children.length) {
tree.children.some(data => (result = searchFn(data, name)));
}
return result;
};
console.log(searchFn(tree, "A-1-A"));
console.log(searchFn(tree, "A-1"));
console.log(searchFn(tree, ""));
.as-console-row {color: blue!important}
You can try something like this
let tree = { name: "A", children: [{ name: 'A-1', children: [{ name: "A-1-A" }, { name: "A-1-B" }] }, { name: 'B-1', children: [{ name: "B-1-A", children: [{ name: "B-11-A" }, { name: "B-11-B" }] }, { name: "B-1-B" }] }] };
function searchFn(obj, text){
if(obj.name === text) return obj
else{
if(obj && obj.children && Array.isArray(obj.children)){
for(let value of obj.children){
if(searchFn(value, text)){
return searchFn(value, text)
}
}
}
}
return null
}
console.log(searchFn(tree, 'A-1'))
console.log(searchFn(tree, 'A-1-A'))
console.log(searchFn(tree, 'A-A-A'))
The problem with your function is that it only checks for the popped element from the array in the children property of the passed object, and not the other elements. Try this:
function searchFn(obj ,searchText) {
if(obj.name === searchText) return obj;
if(obj.children) {
for (let x of obj.children) {
let y = searchFn(x,searchText);
if (y)
return y;
}
}
return null;
}
I have the following data stored in a variable:
let categories = [
{
name: "a",
nodes: [
{
name: "aa",
nodes: [
{
name: "aaa"
}
]
},
{
name: "ab",
},
{
name: "ac",
},
{
name: "ad",
}
]
},
{
name: "b",
nodes: [
{
name: "ba",
},
{
name: "bb",
},
{
name: "bc",
},
{
name: "bd",
}
]
}
];
And I have the following recursive function which accepts the categories variable and name.
function getCategoryParents(categories, name) {
for (let index = 0; index < categories.length; index++) {
const category = categories[index];
if (category.name === name) {
}
if (category.nodes && category.nodes.length) {
category.nodes.forEach(cat => this.getCategoryParents([cat], name));
}
}
}
I want to return an array of names containing the name in the parameter and the parents of that name.
For example if I called getCategoryParents(categories, "aaa") it should returns ["a", "aa", "aaa"]. because aa is the parent of aaa and a is the parent of aa.
I hope it's clear.
I tweaked your function so it would actually return some values when it finds the matches :
function getCategoryParents(arr, name) {
for (let child of arr) {
if (child.name === name) {
return name;
} else if (child.nodes.length > 0) {
var x = getCategoryParents(child.nodes, name);
if (x) return Array.isArray(x) ? [child.name, ...x] : [child.name, x];
}
}
}
let categories = [
{
name: "a",
nodes: [
{
name: "aa",
nodes: [
{
name: "aaa"
}
]
},
{
name: "ab"
},
{
name: "ac"
},
{
name: "ad"
}
]
},
{
name: "b",
nodes: [
{
name: "ba"
},
{
name: "bb"
},
{
name: "bc"
},
{
name: "bd"
}
]
}
];
const result = getCategoryParents(categories, "aaa");
console.log(result); // ["a", "aa", "aaa"]
I have a nested array ,i want to push new item to nested array.
FoodNode= [
{
name: 'Fruit',
parent:'root',
children: [
{name: 'Apple',parent:'Fruit'},
{name: 'Banana',parent:'Fruit'},
{name: 'Fruit loops',parent:'Fruit'},
]
}, {
name: 'Vegetables',
parent:'root',
children: [
{
name: 'Green',
parent:'Vegetables',
children: [
]
}, {
name: 'Orange',
parent:'Vegetables',
children: [
]
},
]
},
];
Now i want to add it to childrens of green.
this.fileElements.filter(res => {
if (res.parent === 'root') {
this.fileList.push(res);
} else {
this.fileList.filter((search, index) => {
if (search.name === res.parent) {
console.log(typeof search.children === 'undefined');
search.children.push(res);
}
});
}
});
this code push the item to 1 level only (like immediate children),bases on parent value Im pushing element to the children.I'm using mat-tree so I need same structure.please help
Hope it helps.
this.FoodNode.forEach(e => {
if (e.name == "Vegetables") {
let abcd = e.children;
abcd.forEach(e1 => {
if (e1.name === "Green") {
let data = [
{ name: "Apple" },
{ name: "Banana" },
{ name: "Fruit loops" }
];
data.forEach(e2 => {
e1["children"].push(e2);
});
}
});
}
});
This question already has answers here:
Group array items using object
(19 answers)
Closed 3 years ago.
I have an array Object which has same Id and different values. I need an output with same id and different values merged to the id.
Input:
let data = [{
id: 1,
value: 'Honda'
},
{
id: 2,
value: 'Fiat'
},
{
id: 2,
value: 'Porche'
},
{
id: 1,
value: 'Benz'
}
];
Output:
result = [{
id: 1,
value: ['Honda', 'Benz']
}, {
id: 2,
value: ['Fiat', 'Porche']
}
Hope it will helps you. But this question is duplicate
let data = [{
id: 1,
value: 'Honda'
},
{
id: 2,
value: 'Fiat'
},
{
id: 2,
value: 'Porche'
},
{
id: 1,
value: 'Benz'
}
];
var output = [];
data.forEach(function(item) {
var existing = output.filter(function(v, i) {
return v.id == item.id;
});
if (existing.length) {
var existingIndex = output.indexOf(existing[0]);
output[existingIndex].value = output[existingIndex].value.concat(item.value);
} else {
if (typeof item.value == 'string')
item.value = [item.value];
output.push(item);
}
});
console.dir(output);
const data = [{
id: 1,
value: 'Honda'
},
{
id: 2,
value: 'Fiat'
},
{
id: 2,
value: 'Porche'
},
{
id: 1,
value: 'Benz'
}
];
const expectedResult = [{
id: 1,
value: ['Honda', 'Benz']
}, {
id: 2,
value: ['Fiat', 'Porche']
}
];
const result = [];
data.forEach((e, i) => {
const indexOfExisting = result.findIndex(x => x.id === e.id);
if (indexOfExisting === -1) {
result.push({
id: e.id,
value: [e.value]
})
} else {
result[indexOfExisting].value.push(e.value);
}
});
// console.log(result)
console.log(expectedResult)
You can use Array.prototype.reduce() to achieve it.
let data = [{
id: 1,
value: 'Honda'
},
{
id: 2,
value: 'Fiat'
},
{
id: 2,
value: 'Porche'
},
{
id: 1,
value: 'Benz'
}
];
let result = data.reduce((acc, ele) => {
let filtered = acc.filter(el => el.id == ele.id)
if (filtered.length > 0) {
filtered[0]["value"].push(ele.value);
} else {
element = {};
element["id"] = ele.id;
element["value"] = []
element["value"].push(ele.value);
acc.push(element)
}
return acc;
}, [])
console.log(result)