filter array based on ObjectId - javascript

So I have 2 arrays here, let say
const users = [{_id:ObjectId("6274fb5b82bcc9b2ccc0a361"), name:p1, age:10},
{_id:ObjectId("6274fbc382bcc9b2ccc0a362"), name:p2, age:15},
{_id:ObjectId("6277a3d5b66c061096222bbd")}, name:p3, age:20];
const filterArray = [ObjectId("6274fbc382bcc9b2ccc0a362"),ObjectId("6277a3d5b66c061096222bbd")];
I want to filter result based on matching ObjectId, here's what I'm trying to do
const filteredUsers = users.filter(user=> !!filterArray.includes(user._id));
I'm expecting this result
filteredUsers = [{_id:ObjectId("6274fbc382bcc9b2ccc0a362"), name:p2, age:15},
{_id:ObjectId("6277a3d5b66c061096222bbd")}, name:p3, age:20]

Try to map the filterArray to an array of Strings and use that for comparison:
const filterArray = [ObjectId("6274fbc382bcc9b2ccc0a362"),ObjectId("6277a3d5b66c061096222bbd")];
const mappedFilterArray = filterArray.map(id => id.toString());
const filteredUsers = users.filter(user=> !!mappedFilterArray.includes(user._id.toString()));

You must convert it to string then filter it:
const users = [
{ _id: ObjectId('6274fb5b82bcc9b2ccc0a361'), name: 'p1', age: 10 },
{ _id: ObjectId('6274fbc382bcc9b2ccc0a362'), name: 'p2', age: 15 },
{ _id: ObjectId('6277a3d5b66c061096222bbd'), name: 'p3', age: 20 }
]
const filterArray = [
ObjectId('6274fbc382bcc9b2ccc0a362'),
ObjectId('6277a3d5b66c061096222bbd')
]
const stringFilterArray = filterArray.map(item => item.toString())
const filteredUsers = users.filter(user => stringFilterArray.includes(user._id.toString()))
/* result
[
{ _id:ObjectId("6274fbc382bcc9b2ccc0a362"), name:p2, age:15 },
{ _id:ObjectId("6277a3d5b66c061096222bbd"), name:p3, age:20 }
]
*/

Related

Intersect 3 arrays in Javascript - With snippet

I'm trying to intersect array1 and array2 and find the elements that contain the same name.
Then on array3 I only want to keep the elements that exist on the first intersection by name.
I'm stuck here, I just get true and falses. Any help?
const array1 = [{
name: 'John'
}];
const array2 = [{
name: 'Elisa'
}, {
name: 'John'
}];
const array3 = [{
name: 'Elisa',
age: 10
}, {
name: 'John',
age: 23
}, {
name: 'Maria',
age: 30
}];
const intersectArray = array1.map(elem1 => array2.map(elem2 => elem1.name === elem2.name));
console.log(intersectArray);
const filteredArray = array3.map(elem3 => intersectArray.map(elem => elem.name === elem3.name));
console.log(filteredArray);
The expected result should be:
{ name: 'John', age: 23 }
You can just check against both arrays, instead of first creating an intersection:
const array1 = [{ name: 'John' }];
const array2 = [{ name: 'Elisa' }, { name: 'John' }];
const array3 = [{ name: 'Elisa', age: 10 }, { name: 'John', age: 23 }, { name: 'Maria', age: 30 }];
const result = array3.filter(x =>
array1.some(a => a.name === x.name) &&
array2.some(a => a.name === x.name))
console.log(result);
To do what you require you can use filter() to return only the elements which meet certain criteria. In your case, you can find() within the other array if a matching name is found.
The same logic can be used for both steps:
const array1 = [{ name: 'John' }];
const array2 = [{ name: 'Elisa' }, { name: 'John' }];
const array3 = [{ name: 'Elisa', age: 10 }, { name: 'John', age: 23 }, { name: 'Maria', age: 30 }];
const intersectArray = array1.filter(o1 => array2.find(o2 => o1.name == o2.name));
console.log(intersectArray);
const filteredArray = array3.filter(o3 => intersectArray.find(ia => o3.name === ia.name));
console.log(filteredArray);
If you want to grab the intersection between three arrays, you can filter the first array and find a similar item in the second array with some.
const
intersection = (a, b, f) => a.filter(x => b.some(y => f(x) === f(y))),
intersection2 = (f, ...a) => a.reduce((r, b) => intersection(r, b, f));
const
arr1 = [{ name: 'John' }],
arr2 = [{ name: 'Elisa' }, { name: 'John' }],
arr3 = [{ name: 'Elisa', age: 10 }, { name: 'John', age: 23 }, { name: 'Maria', age: 30 }];
const
getName = ({ name }) => name,
inter1 = intersection(arr3, intersection(arr2, arr1, getName), getName),
inter2 = intersection2(getName, arr3, arr2, arr1);
console.log(inter1); // Nested calls
console.log(inter2); // Reduction
.as-console-wrapper { top: 0; max-height: 100% !important; }

How to change property name in array of objects in Javascript?

I have an array of objects -
const obj = [{name:'josh', city:'Sydney'},{name:'alice', city:'York'}]
I want to change 'city' property to 'town'. How can I make this change to the property of each object in the array?
Using Array#map:
const arr = [ { name: 'josh', city: 'Sydney' }, { name: 'alice', city: 'York' } ];
const res = arr.map(({ city, ...e }) => ({ ...e, town: city }));
console.log(res);
Using Array#forEach:
const arr = [ { name: 'josh', city: 'Sydney' }, { name: 'alice', city: 'York' } ];
arr.forEach(e => {
e.town = e.city;
delete e.city;
});
console.log(arr);
You can't do this directly, but what you can do is this:
const obj = [{name:'josh', city:'Sydney'},{name:'alice', city:'York'}]
for (let element of obj){
element.town = element.city;
delete element.city;
}

Write data from two arrays in one document

I have some data to be combined in one document in the mongoDB.
I have two arrays
const users = ['Anna', 'Jack', 'Paul', 'Elena']
const additionalData = ['data1', 'data2', 'data3', 'data4', 'data5']
for(const i of users){
const user = {
username: i.username
};
for(const key of additionalData){
user.keyword = key
}
await User.create(model)
}
[
{
username: 'Anna',
keyword: 'data1'
},
{
username: 'Jack',
keyword: 'data2'
},
{
username: 'Paul',
keyword: 'data3'
},
{
username: 'Elena',
keyword: 'data4'
}
]
I need to combine those arrays in the one document
Try this, You just need to loop through users and get data from additionalData with the current index. You can achieve this in 2 ways
Native Way
const users = ['Anna', 'Jack', 'Paul', 'Elena'];
const additionalData = ['data1', 'data2', 'data3', 'data4', 'data5'];
const newArray = [];
for (let i = 0; i < users.length; i += 1) {
const user = users[i];
const obj = { userName: user, keyword: additionalData[i] || null };
newArray.push(obj);
}
console.log(newArray);
ES6 Way
const users = ['Anna', 'Jack', 'Paul', 'Elena'];
const additionalData = ['data1', 'data2', 'data3', 'data4', 'data5'];
const result = users.map((r, i) => {
const obj = { userName: r, keyword: additionalData[i] || null };
return obj;
});
console.log(result)
// Users and additionalData array
const users = ['Anna', 'Jack', 'Paul', 'Elena'];
const additionalData = ['data1', 'data2', 'data3', 'data4', 'data5'];
// Merge them with this
$.merge( $.merge( [], users ), additionalData );

Compare a string in an array with a string after the array in the filter method

competences['asset']['id'] return me string in array ['123'];
select[0] return me string '123'
How compare the string in the array with the string after the array so that it is on one line
.filter (obj => obj [" competences "]. map (competences => competences ['asset']
['id']) !== [select[0]]) // ['234']! = = '234
I'm trying to get inside the array:
obj["competences"].map (competences => competences['asset']['id'][0])
but this returns the first character of the string for me.
Code here: https://stackblitz.com/edit/react-lwyqns
const people = [
{
'firstname': "Paul",
'id': "12345",
'competences': [
{'asset': {
'name': "Paul",
'id': '234'
}
}
]
}
]
const select = [
"123",
"456",
"789",
"234"
]
const sort = people
.filter(obj => obj["competences"].map(competences => competences['asset']['id']) !== select[0]) //['234'] !== '234'
.map(
(obj, i) => {
return obj;
}
)
console.log(sort)
Here's code for which return people object whose competences.$.asset.id not include in select id array.
const people = [
{
firstname: 'Paul',
id: '12345',
competences: [
{
asset: {
name: 'Paul',
id: '234'
}
}
]
},
{
firstname: 'SPaul',
id: '123456',
competences: [
{
asset: {
name: 'SPaul',
id: '100'
}
}
]
}
];
const select = ['123', '456', '789', '234'];
// if you want to return people data if all competences.asset.id not in select
const sort = people.filter((item) => item.competences.filter((x) => select.indexOf(x.asset.id) === -1).length === item.competences.length);
// if you want to return people data if some competences.asset.id not in select
const xSort = people.filter((item) => item.competences.filter((x) => select.indexOf(x.asset.id) === -1).length > 0);
console.log(sort);
console.log(xSort);

JavaScript loop through two arrays and get single array

I have two arrays:
var arr = [
{ id: 2, username: 'bill'},
{ id: 3, username: 'ted' }];
var b = ["ted", "bill", "john"];
how can I get one array like this:
var finalArr = [{id: 2, username: 'bill'},{id:3, username: 'ted'}. {id:0, username: 'john'}]
If user from array b exist in arr array to add id and if not id to be 0.
I tried something like this, but not working
var arr = [{
id: 2,
username: 'bill'
},
{
id: 3,
username: 'ted'
}
];
var b = ["ted", "bill", "john"];
var finalArr = [];
function userExists(username) {
var a = arr.some(item => {
if (item.username === username) {
finalArr.push({
username,
id: item.id
})
} else {
finalArr.push({
username,
id: 0
})
}
})
}
b.forEach(el => {
userExists(el)
})
console.log(finalArr)
Loop through b using map. Check if the username exists in arr using find. If yes, return the object. Else, return a new object with id: 0
var arr = [
{ id: 2, username: 'bill'},
{ id: 3, username: 'ted' }];
var b = ["ted", "bill", "john"];
const output = b.map(username => {
const found = arr.find(a => a.username === username);
return found || { username, id: 0 }
})
console.log(output)
You can use map and find to construct your new array like
var arr = [{
id: 2,
username: 'bill'
},
{
id: 3,
username: 'ted'
}
];
var b = ["ted", "bill", "john"];
const finalArr = b.map(username => {
const find = arr.find(o => o.username === username);
return find ? find : { id: 0, username }
})
console.log(finalArr)
You can do that using reduce method.
b.reduce((result, elm) => {
const userObj = arr.find((a) => a.username === elm);
if(userObj) {
result.push(userObj)
} else {
result.push({
id: 0,
username: elm
});
}
return result;
}, []);
Check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce for more details about reduce.
You can craete a dummy array for storing result and , find the existing using find. If not found create dummy object and push inside array.
var arr = [
{ id: 2, username: 'bill'},
{ id: 3, username: 'ted' }];
var b = ["ted", "bill", "john"];
myArr = [];
b.forEach(function(element) {
var el=arr.find(x => x.username === element);
if(el){
myArr.push(el);
}else{
var dummy={};
dummy.id=0;
dummy.username=element;
myArr.push(dummy);
}
});
console.log(myArr);
You could take a Set and filter by looking to the set and delete visited items. At the end concat missing items.
This solution repsects the order of the given data and adds the missing object in order of the names array.
var data = [{ id: 42, username: 'foo' }, { id: 2, username: 'bill' }, { id: 3, username: 'ted' }],
names = ["ted", "bill", "john"],
missing = new Set(names),
result = data
.filter(({ username }) => missing.delete(username))
.concat(Array.from(missing, username => ({ id: 0, username })));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Categories

Resources