Filtering an array by using another array - javascript

Array1 = [ name1, name2];
Array2 = [ { name: name1 , id: 1, location: xyz, address: 123 },
{ name: name2 , id: 2, location: abc, address: 456 },
{ name: name3 , id: 3, location: def, address: 234 },
{ name: name4 , id: 4, location: ghi, address: 789 }
];
I have 2 arrays - Array1 and Array2. I want to filter Array2 by using Array1 such that my output comes as - [ { name: name1 , id: 1 }, { name: name2 , id: 2 }]. I tried like this - var ids = _.pluck(_.filter(Array2, a => _.contains(Array1, a.id)), 'id'); but problem with this is it's only giving one thing at a time means I can only get either name or id or location or address at a time but I want to filter name and id both at a time.

Loop over the second array and for each item look if the first contains it. If contains, includes will return true and that element will be in a new array.
Be aware this works only in ES6
var arr1 = [ 'A', 'B'];
var arr2 = [ { name: 'A' , id: 1,address: 123 },
{ name: 'B' , id: 2, address: 456 },
{ name: 'C' , id: 3, address: 234 },
{ name: 'D' , id: 4,address: 789 }
];
var newArr = arr2.filter(item => arr1.includes(item.name)).map(item => ({ name: item.name, id: item.id}));
console.log(newArr);

You could use a hash table for faster check if the wanted names are in the item for filtering.
var array1 = ['name1', 'name2'],
array2 = [{ name: 'name1', id: 1, location: 'xyz', address: 123 }, { name: 'name2', id: 2, location: 'abc', address: 456 }, { name: 'name3', id: 3, location: 'def', address: 234 }, { name: 'name4', id: 4, location: 'ghi', address: 789 }],
result = array2.filter(function (a) {
var hash = Object.create(null);
a.forEach(function (k) { hash[k] = true; });
return function (b) { return hash[b.name]; };
}(array1));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Instead of having to .filter and then .map it, just use .reduce.
Using reduce and includes, you can have something like this:
var Array1 = ["name1", "name2"];
var Array2 = [{
name: "name1",
id: 1,
location: "xyz",
address: 123
},
{
name: "name2",
id: 2,
location: "abc",
address: 456
},
{
name: "name3",
id: 3,
location: "def",
address: 234
},
{
name: "name4",
id: 4,
location: "ghi",
address: 789
}
];
var result = Array2.reduce((arr, cur) => {
if(Array1.includes(cur.name)) {
arr.push({
name: cur.name,
id: cur.id
})
}
return arr
}, [])
console.log(result)
Note, that you can use indexOf instead of includes if needing to support older browsers.

Related

Replace the records of particular category

There is one scenario where i need to replace the existing records from cached data with new incoming data source. Looking for the cleaner approach to handle the array operations.
For example:
var userCategory = [
{
id: 'platinum',
name: 'bob',
},
{
id: 'platinum',
name: 'bar',
},
{
id: 'platinum',
name: 'foo',
},
{
id: 'gold',
name: 'tom',
},
{
id: 'silver',
name: 'billy',
},
];
Here is new users of particular category
var newPlatinumUsers = [
{
id: 'platinum',
name: 'bob',
},
{
id: 'platinum',
name: 'mike',
},
];
This is the expected result needed:
var expected = [
{
id: 'platinum',
name: 'bob',
},
{
id: 'platinum',
name: 'mike',
},
{
id: 'gold',
name: 'tom',
},
{
id: 'silver',
name: 'billy',
},
];
I tried with filtering all the platinum user from existing records then added the new records but it looks verbose
Is there any cleaner approach like lodash operator??
Thanks for your time!!!
May you are looking for this.
function getUnique(arr){
// removing duplicate
let uniqueArr = [...new Set(arr)];
document.write(uniqueArr);
}
const array = ['acer','HP','Apple','Apple','something'];
// calling the function
getUnique(array);
Verify my answer if it help you.
Please find the Javascript implementation of the same
var userCategory = [
{ id: 'platinum', name: 'bob', },
{ id: 'platinum', name: 'bar', },
{ id: 'platinum', name: 'foo', },
{ id: 'gold', name: 'tom', },
{ id: 'silver', name: 'billy', },
];
var newPlatinumUsers = [
{ id: 'platinum', name: 'bob', },
{ id: 'platinum', name: 'mike', },
];
const result = [...newPlatinumUsers];
userCategory.forEach((node) => {
if(node.id !== 'platinum') {
result.push(node);
}
});
console.log(result);
With this solution you can change more than one category:
var userCategory = [
{id: 'platinum',name: 'bob'},
{id: 'platinum',name: 'bar'},
{id: 'platinum',name: 'foo'},
{id: 'gold',name: 'tom'},
{id: 'silver',name: 'billy'},
];
var newUsers = [
{id: 'platinum',name: 'bob'},
{id: 'platinum',name: 'mike'},
{id: 'gold',name: 'will'},
{id: 'gold',name: 'jerry'},
];
const idsToReplace = {}
const result = [...newUsers]
result.forEach(u => {
idsToReplace[u.id] = true
})
userCategory.forEach(u => {
if(!idsToReplace[u.id]){
result.push(u)
}
})
console.log(result)

Return a subarray with a value changed to reflect parent object

I am trying to change the value of single key in an associative array which is inside another assoc array using javascript.
I have an array like this:
let arr = [{
id: 4,
name: 'test',
docs: [{
id: 1,
name: 'abc'
},{
id: 2,
name: 'xyz'
}]
}, {
id: 8,
name: 'test2',
docs: [{
id: 5,
name: 'abc'
},{
id: 7,
name: 'xyz'
}]
}]
I want to change the value of name of xyz to xyz (test), where test is name key of parent object and get final array as Output:
[{
id: 1,
name: 'abc (test)'
},
{
id: 2,
name: 'xyz (test)'
},
{
id: 5,
name: 'abc (test2)'
},
{
id: 7,
name: 'xyz (test2)'
}]
I am using approach.
let docs = new Array();
arr.forEach((item, index) => {
let docx = item.documents.map(item1 => {
item1.name = item1.name + " ("+item.name+")";
});
docs.push(docx);
});
return docs;
this is returning array of undefined array.
Try a flatMap
let arr = [{ id: 4, name: 'test', docs: [{ id: 1, name: 'abc' },{ id: 2, name: 'xyz' }] }, { id: 8, name: 'test2', docs: [{ id: 5, name: 'abc' },{ id: 7, name: 'xyz' }] }]
const output = arr.flatMap(item =>
item.docs.map(({id,name}) => ({ id, name: `${name} (${item.name})` }))
)
console.log(output)
There is an issue in your data, the docs inner array contains an object with duplicate keys:
let arr = [{
id: 4,
name: 'test',
docs: [{
id: 1,
name: 'abc',
id: 2, // <-- duplicate key
name: 'xyz' // <-- duplicate key
}]
},
If I remove the duplication, you can use this code to create a new object with the name value updated to xyz123 if the original value was xyz:
const original = [{
id: 4,
name: 'test',
docs: [{
id: 1,
name: 'abc'
}, {
id: 2,
name: 'xyz'
}]
}, {
id: 8,
name: 'test2',
docs: [{
id: 1,
name: 'abc'
}, {
id: 2,
name: 'xyz'
}]
}];
const updates = original.map(currentObject => {
const newObject = Object.assign(currentObject);
const newDocs = newObject.docs.map(doc => {
const newDoc = Object.assign(doc);
if (newDoc.name === "xyz") {
newDoc.name = "xyz123";
}
return newDoc;
});
newObject.docs = newDocs;
return newObject
});
console.log(updates);

Compare two array of objects in javascript/angular and return as soon first condition satisfies (any lodash operator)

Say I have two arrays of objects:
let ar1 = [{
id: 1,
name: 'abc',
job: 'dev'
}, {
id: 2,
name: 'xyz',
job: 'qa'
},{
id: 3,
name: 'pqr',
job: 'dev'
}
];
let arr2 = [{
id: 1,
name: 'abc',
job: 'dev'
},{
id: 2,
name: 'zzz',
job: 'qa'
},{
id: 3,
name: 'pqr',
job: 'dev'
}];
I need to compare them so that I get 'true' and exit the comparison without iterating further as the name is different in the second element between two objects.
I tried with the following code:
private compareObjects(obj1, obj2) {
obj1.forEach((x) => {
obj2.forEach((y) => {
if (x.id === y.id) {
return (!_.isEqual(x, y));
}
});
});
}
I suggest reduce-ing the second array to what's needed for testing the first array: { id : name }. This is a single pass on the second array.
Then use find to test the first array with a single pass that halts on the first mismatch.
let ar1 = [{
id: 1,
name: 'abc',
job: 'dev'
}, {
id: 2,
name: 'xyz',
job: 'qa'
},{
id: 3,
name: 'pqr',
job: 'dev'
}
];
let arr2 = [{
id: 1,
name: 'abc',
job: 'dev'
},{
id: 2,
name: 'zzz',
job: 'qa'
},{
id: 3,
name: 'pqr',
job: 'dev'
}];
let index = arr2.reduce((acc, e) => {
acc[e.id] = e.name
return acc
}, {})
let firstMismatched = ar1.find(e => index[e.id] !== e.name)
console.log(firstMismatched)

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/

How to replace existing array objects of one array to another array in javascript

var arr1 = [{
id: '111',
name: 'aaa'
}, {
id: '222',
name: 'bbb'
}, {
id: '333',
name: 'ccc'
}, {
id: '444',
name: 'ddd'
}];
var arr2 = [{
id: '111',
name: 'xyz'
}, {
id: '333',
name: 'abc'
}];
my requirement: I need to replace aar1 with arr2 having same id in arr2 but different name value.
Below Result i should get in arr1
var arr1 = [{
id: '111',
name: 'xyz'
}, {
id: '222',
name: 'bbb'
}, {
id: '333',
name: 'abc'
}, {
id: '444',
name: 'ddd'
}];
you can use map and find to replace arr2 name in arr1.
map function iterate through each elements of arr1, find will match both id and return matched object if found. if we don't find we will just return arr1 item using || operator.
const result = arr1.map(item => arr2.find(item2 => item.id === item2.id) || item)
Working example:
var arr1 = [{
id: '111',
name: 'aaa'
}, {
id: '222',
name: 'bbb'
}, {
id: '333',
name: 'ccc'
}, {
id: '444',
name: 'ddd'
}];
var arr2 = [{
id: '111',
name: 'xyz'
}, {
id: '333',
name: 'abc'
}];
const result = arr1.map(item => arr2.find(item2 => item.id === item2.id) || item)
console.log(result)
This is my interpretation of the question.
Only copy the name if the id is found in arr2.
arr1.forEach(e1 => {
var e2 = arr2.find( e => e.id === e1.id );
if (e2) { e1.name = e2.name; }
});

Categories

Resources