JavaScript - filter in loop, create duplicate - javascript

I want to filter an array with another array in order to know if there are new people.
const people = [
{ "name": "jerry" },
{ "name": "tom" },
{ "name": "alex" }
]
const newList = [
{ "name": "bran" },
{ "name": "jerry" },
{ "name": "john" }
]
const new_people = []
for (const pp of people) {
let result = newList.filter(newL => newL.name != pp.name)
if (result) {
new_people.push(result)
}
}
console.log(new_people)
This is the result:
[
[ { name: 'bran' }, { name: 'john' } ],
[ { name: 'bran' }, { name: 'jerry' }, { name: 'john' } ],
[ { name: 'bran' }, { name: 'jerry' }, { name: 'john' } ]
]
But I'm looking for:
[ { name: 'bran' }, { name: 'john' } ]
I would like to avoid the loop because it makes duplicate in the result but I don't know how I can't do it without the loop.

First make a temporary array of people name:
const peopleNames = people.map(pp => pp.name);
Then the peopleNames will be as follows:
['jerry', 'tom', 'alex']
Now filter the new people from the newList:
const newPeople = newList.filter(pp => !peopleNames.includes(pp.name));
The newPeople will be an array of objects that you are looking for.
[{name: 'bran'}, {name: 'john'}]

const people = [
{ "name": "jerry" },
{ "name": "tom" },
{ "name": "alex" }
]
const newList = [
{ "name": "bran" },
{ "name": "jerry" },
{ "name": "john" }
]
const output = newList.filter(a => people.filter(x => x.name == a.name).length == 0);
console.log('By USing Filter', output);
//filter the newList and retain those object, which are not present in the people
//Way 2: By using some
//const output2 = newList.filter(a => !people.some(x => x.name == a.name));
//console.log('By Using Some', output2);

You can use Array's reduce method to get the desired result:
const new_people = newList.reduce((accVal, e) =>
(people.map(p => p.name).includes(e.name))
? accVal
: accVal.concat({ "name": e.name } ),
[ ] )

Related

Group array of object into shorter array of object [duplicate]

This question already has answers here:
Group array items using object
(19 answers)
How can I group an array of objects by key?
(32 answers)
Closed 7 months ago.
I want to make this
const arr = [
{
"name": "mac"
},
{
"group": "others",
"name": "lenovo"
},
{
"group": "others",
"name": "samsung"
}
]
into this:
[
{
name: 'mac',
},
{
name: 'others',
group: [
{
name: 'lenovo',
},
{
name: 'samsung',
},
],
}
]
I tried to use normal forEach loop but it didn't turn out well:
let final = []
const result = arr.forEach(o => {
if(o.group) {
group = []
group.push({
name: o.name
})
final.push(group)
} else {
final.push(o)
}
});
Not sure if reduce might help? before I try lodash groupBy I want to use just pure js to try to make it.
Hope this answer will work for you.
const arr = [
{
name: "mac",
},
{
group: "others",
name: "lenovo",
},
{
group: "others",
name: "samsung",
},
];
const temp = [];
arr.forEach((e) => {
if (!e.group) {
temp.push(e);
} else {
const index = temp.findIndex((ele) => ele.name === e.group);
if (index === -1) {
obj = {
name: e.group,
group: [{ name: e.name }],
};
temp.push(obj)
} else {
temp[index].group.push({ name: e.name });
}
}
});
console.log(temp);
instead of creating and pushing group array in final again and again u should just push group in the end of foreach
like this--
let final = []
let group = []
const result = arr.forEach(o => {
if(o.group) {
group.push({
name: o.name
})
} else {
final.push(o)
}
})
final.push({name: "others", group})

Filter one array by another array [duplicate]

This question already has answers here:
Filter array of objects with another array of objects
(11 answers)
Closed 1 year ago.
const items = [[{name:"p2"},{name:"p3"}, {name:"p7"},{name:"p9"},{name:"p1"}],[{name:"p6"}, {name:"p3"},{name:"p7"}, {name:"p9"},{name:"p2"}],[{name:"p3"},{name:"p6"}, {name:"p7"},{name:"p9"},{name:"p4"}],[{name:"p2"}, {name:"p3"},{name:"p1"}, {name:"p9"},{name:"p6"}]]
const findObj = [{name:"p1"},{name:"p2"},{name:"p6"}]
Find the child array of sets which have all three element from findobj object
You can easily achieve the result using filter, Set and reduceas:
const items = [
[
{ name: "p2" },
{ name: "p3" },
{ name: "p7" },
{ name: "p9" },
{ name: "p1" },
],
[
{ name: "p6" },
{ name: "p3" },
{ name: "p7" },
{ name: "p9" },
{ name: "p2" },
],
[
{ name: "p3" },
{ name: "p6" },
{ name: "p7" },
{ name: "p9" },
{ name: "p4" },
],
[
{ name: "p2" },
{ name: "p3" },
{ name: "p1" },
{ name: "p9" },
{ name: "p6" },
],
];
const findObj = [{ name: "p1" }, { name: "p2" }, { name: "p6" }];
const set = new Set(findObj.map((o) => o.name));
const result = items.filter((arr) => {
const remain = arr.reduce((acc, curr) => {
if (set.has(curr.name)) acc.add(curr.name);
return acc;
}, new Set());
return remain.size === set.size;
});
console.log(result);
const items = [[{name:"p2"},{name:"p3"}, {name:"p7"},{name:"p9"},{name:"p1"}],[{name:"p6"}, {name:"p3"},{name:"p7"}, {name:"p9"},{name:"p2"}],[{name:"p3"},{name:"p6"}, {name:"p7"},{name:"p9"},{name:"p4"}],[{name:"p2"}, {name:"p3"},{name:"p1"}, {name:"p9"},{name:"p6"}]]
const findObj = [{name:"p1"},{name:"p2"},{name:"p6"}]
const result = items.filter(item=>{
const childItem = item.map(childItem=>childItem.name);
let allExist=true;
findObj.forEach(obj=>{
if(!childItem.includes(obj.name)){
allExist=false;
}
})
return allExist;
})
console.log(result)
Using filter and get all names from each item by using map .map(prop=>prop.name) or more simple with destructuring .map(({name})=>name) and filter items that names are included in findObj
const items = [[{name:"p2"},{name:"p3"}, {name:"p7"},{name:"p9"},{name:"p1"}],[{name:"p6"}, {name:"p3"},{name:"p7"}, {name:"p9"},{name:"p2"}],[{name:"p3"},{name:"p6"}, {name:"p7"},{name:"p9"},{name:"p4"}],[{name:"p2"}, {name:"p3"},{name:"p1"}, {name:"p9"},{name:"p6"}]]
const findObj = [{name:"p1"},{name:"p2"},{name:"p6"}]
const result = items.filter(item=>{
const arrProp = item.map(prop=>prop.name)
const filtProp = findObj.map(({name})=>name)
return filtProp.every(x=>arrProp.includes(x));
})
console.log(result)

Create an array of objects recursively based in array of objects

I have an array of objects like this:
myArr = [
{ "id": "aaa.bbb" },
{ "id": "aaa.ccc" },
{ "id": "111.222" },
{ "id": "111.333" },
]
My goal is to be able to have a new array for every part of the Id, while nesting the old array. Like this:
newArray = [
{
"id": "aaa",
"children": [{ "id": "aaa.bbb" }]
},
{
"id": "aaa",
"children": [{ "id": "aaa.ccc" }]
},
{...}
]
The idea is to be able to do It with multiple substrings if there is a bigger Id
You could use map to iterate through the array and mutate the objects in place
myArr = [ { "id": "aaa.bbb" }, { "id": "aaa.ccc" }, { "id": "111.222" }, { "id": "111.333" }, ]
result=myArr.map((o)=>({["id"]:o.id.split(".")[0],["children"]:[o]}))
console.log(result)
alternatively you could use reduce
myArr = [ { "id": "aaa.bbb" }, { "id": "aaa.ccc" }, { "id": "111.222" }, { "id": "111.333" }, ]
result=myArr.reduce((acc,curr)=>acc=[...acc,{["id"]:curr.id.split(".")[0],["children"]:[curr]}],[])
console.log(result)
Use Array.prototype.map.
const newArray = myArr.map( function( e ) {
const oldId = e.id;
const newElement = {
id: oldId.split( '.' )[0],
children: [ e ]
};
return newElement
} );
Simplified:
const newArray = myArr.map( function( e ) {
return {
id: e.id.split( '.' )[0],
children: [ e ]
};
} );
Further:
const newArray = myArr.map( e => { id: e.id.split( '.' )[0], children: [ e ] } );

How to find a key by value in Javascript?

I'm new to Javascript and react. I have a react app with the following array and a function to find a key inside the array. I'm providing the search value as parameter and I need to find the key which has the search value. I have three user roles as client, admin and manager. I'm doing the code as follows
Array:
{
client:[{ id:1, name:"Adam" },
{ id:2, name:"Mon" },
{ id:3, name:"Sara" }],
admin:[{ id:4, name:"Jake" },
{ id:5, name:"Jon" },
{ id:6, name:"Sean" }],
manager:[{ id:7, name:"Doe" },
{ id:8, name:"Matt" },
{ id:9, name:"Mark" }]
}
I need to find the user role by given id. This is what I tried.
Component:
roleCheck = (searchId) => {
var roles = this.state.array;
Object.keys(roles).forEach(role => {
Object.keys(role).forEach(user => {
if (user.id === searchId){
return role;
}
});
});
}
The result is always Undefined. How can I solve this?
You're not returning any thing from you function. You can change your coe in following manner
roleCheck = (searchId) => {
var roles = this.state.array;
let output = 'Not found'
Object.keys(roles).forEach(role => {
Object.keys(role).forEach(user => {
if (user.id === searchId){
output = role
}
});
});
return output;
}
Or alternatively You can use find and some
let data = {client:[{ id:1, name:"Adam" },{ id:2, name:"Mon" },{ id:3, name:"Sara" }],admin:[{ id:4, name:"Jake" },{ id:5, name:"Jon" },{ id:6, name:"Sean" }],manager:[{ id:7, name:"Doe" },{ id:8, name:"Matt" },{ id:9, name:"Mark" }]}
let role = (searchId) => {
return Object.keys(data).find(key => {
return data[key].some(({id})=> id === searchId)
})
}
console.log(role(6))
console.log(role(60))
Your return will only return from the function given to forEach and not the checkRole function.
You could instead use a combination of find and some to figure out what role the person with the searchId has:
const data = {
client: [
{ id: 1, name: "Adam" },
{ id: 2, name: "Mon" },
{ id: 3, name: "Sara" }
],
admin: [
{ id: 4, name: "Jake" },
{ id: 5, name: "Jon" },
{ id: 6, name: "Sean" }
],
manager: [
{ id: 7, name: "Doe" },
{ id: 8, name: "Matt" },
{ id: 9, name: "Mark" }
]
};
function roleCheck(searchId) {
return Object.keys(data).find(key => {
return data[key].some(person => person.id === searchId);
});
}
console.log(roleCheck(8));
using the https://underscorejs.org/ library us can do this
var hash = {
foo: 1,
bar: 2
};
(_.invert(hash))[1]; // => 'foo'
you can put this into your loop
Another way to check if a JavaScript Object has a key is using hasOwnProperty method.
let c = {"name": "John", "id": 12};
c.hasOwnProperty("name") // true

Setting array keys dynamically based on length

Given an array in this format:
[
[{
name: "name",
value: "My-name"
},
{
name: "qty",
value: "1"
},
{
name: "url",
value: "test.com"
},
{
name: "comment",
value: "my-comment"
}
],
[{
name: "name",
value: "My-name2"
},
{
name: "qty",
value: "3"
},
{
name: "url",
value: "test2.com"
}
],
[{
name: "name",
value: "My-name3"
},
{
name: "qty",
value: "1"
},
{
name: "url",
value: "test3.com"
},
{
name: "comment",
value: "my-comment3"
}
]
]
I'm looking to switch that to:
[
[
{ name: "My-name" },
{ qty: "1" },
{ url: "test.com" },
{ comment: "my-comment", }
],[
{ name: "My-name2" },
{ qty: "3" },
{ url: "test2.com",
],[
{ name: "My-name3", },
{ qty: "1", },
{ url: "test3.com", },
{ comment: "my-comment3", }
]
]
In other words, swapping out the array keys but maintaining the object structure within each array element.
I've tried looping over each element and can swap the keys out using something like:
newArray[iCount][item.name] = item.value;
However I'm then struggling to preserve the object order. Note that the comment field may or may not appear in the object.
With Array.map() function:
var arr = [
[{name:"name",value:"My-name"},{name:"qty",value:"1"},{name:"url",value:"test.com"},{name:"comment",value:"my-comment"}],
[{name:"name",value:"My-name2"},{name:"qty",value:"3"},{name:"url",value:"test2.com"}],
[{name:"name",value:"My-name3"},{name:"qty",value:"1"},{name:"url",value:"test3.com"},{name:"comment",value:"my-comment3"}]
],
result = arr.map(function(a){
return a.map(function(obj){
var o = {};
o[obj.name] = obj.value
return o;
});
});
console.log(result);
Check my moreBetterOutput value. I think will be better.
If you still need a result like your example in the question then you can check output value.
const input = [
[
{
name:"name",
value:"My-name"
},
{
name:"qty",
value:"1"
},
{
name:"url",
value:"test.com"
},
{
name:"comment",
value:"my-comment"
}
],
[
{
name:"name",
value:"My-name2"
},
{
name:"qty",
value:"3"
},
{
name:"url",
value:"test2.com"
}
],
[
{
name:"name",
value:"My-name3"
},
{
name:"qty",
value:"1"
},
{
name:"url",
value:"test3.com"
},
{
name:"comment",
value:"my-comment3"
}
]
]
const output = input.map(arr => arr.map(obj => ({[obj.name]: obj.value})))
const moreBetterOutput = output.map(arr => arr.reduce((acc, item, index) => {
acc[Object.keys(item)[0]] = item[Object.keys(item)[0]];
return acc;
}, {}) )
//console.log(output);
console.log(moreBetterOutput);
Another map function:
const result = array.map( subarray =>
Object.assign(...subarray.map( ({name, value}) => ({ [name] : value }) ))
);

Categories

Resources