Finding a key in an object by using values from an array - javascript

I have an array which is dynamically created by selecting items from a list:
[2, 4]
I also have an array of objects:
[{id: 1, name: "Param1"}, {id: 2, name: "Param2"}, {id: 3, name: "Param3"}, {id: 4, name: "Param4"}]
What I need to do is use the values in the first array to match against the ids in the objects in the second array and return those objects.
Help with this would be much appreciated
Thanks for your time

You can use this ES6 code, which turns the first array to a Set to allow fast lookup, and then applies the Array filter method, specifically intended for this purpose:
var select = [2, 4];
var data = [{id: 1, name: "Param1"}, {id: 2, name: "Param2"},
{id: 3, name: "Param3"}, {id: 4, name: "Param4"}]
var selectSet = new Set(select);
var result = data.filter( obj => selectSet.has(obj.id) );
console.log(result);

You can just use for loop as Liam's comment, or you can use the filter method of array like this:
var keys = [2, 4];
var objs = [{id: 1, name: "Param1"}, {id: 2, name: "Param2"}, {id: 3, name: "Param3"}, {id: 4, name: "Param4"}];
function filterById(obj) {
return keys.indexOf(obj.id) != -1;
}
var newArr = objs.filter(filterById);
The newArr is the result you want.

Related

How can I merge two or more arrays containing several objects into one and increment their IDs?

I have three arrays of objects like so
const arr1 = [{id: 1, name: 'Jay'}, {id: 2, name: 'Kay'}];
const arr2 = [{id: 1, name: 'Pete'}, {id: 2, name: 'Liam'}];
const arr3 = [{id: 1, name: 'Baby'}, {id: 2, name: 'Neeson'}, {id: 3, name: 'Kobe'}];
and I want to merge them into a single array like this
const bigArray = [{id: 1, name: 'Jay'}, {id: 2, name: 'Kay'},{id: 3, name: 'Pete'}, {id: 4, name: 'Liam'}, {id: 5, name: 'Baby'}, {id: 6, name: 'Neeson'}, {id: 7, name: 'Kobe'}];
I know I can spread them into a single array using the spread operator but I also need the IDs incremented when they are joined. How can I achieve that?
Reassign the id based on the index:
const merged = [...arr1, ...arr2, ...arr3];
merged.forEach((el, index) => el.id = index + 1);
Add all the array in a single array and than map over it and change index according to need.
const arr1 = [{id: 1, name: 'Jay'}, {id: 2, name: 'Kay'}];
const arr2 = [{id: 1, name: 'Pete'}, {id: 2, name: 'Liam'}];
const arr3 = [{id: 1, name: 'Baby'}, {id: 2, name: 'Neeson'}, {id: 3, name: 'Kobe'}];
let arr = [...arr1,...arr2,...arr3]
let op = arr.map((ele, index) => ({...ele, id: index+1}) )
console.log(op)
You can combine the arrays to a single array using rest parameters and Array.flat(), and then you can use Array.map() to update the objects with the id generated from the index:
const flatAndInc = (...args) =>
args.flat()
.map((o, idx) => ({
...o,
id: idx + 1
}));
const arr1 = [{id: 1, name: 'Jay'}, {id: 2, name: 'Kay'}];
const arr2 = [{id: 1, name: 'Pete'}, {id: 2, name: 'Liam'}];
const arr3 = [{id: 1, name: 'Baby'}, {id: 2, name: 'Neeson'}, {id: 3, name: 'Kobe'}];
const result = flatAndInc(arr1, arr2, arr3);
console.log(result);
You could map new objects without mutating the given data.
const
arr1 = [{id: 1, name: 'Jay'}, {id: 2, name: 'Kay'}],
arr2 = [{id: 1, name: 'Pete'}, {id: 2, name: 'Liam'}],
arr3 = [{id: 1, name: 'Baby'}, {id: 2, name: 'Neeson'}, {id: 3, name: 'Kobe'}],
result = [arr1, arr2, arr3].reduce(
(id => (r, a) => (a.forEach(({ name }) => r.push({ id: id++, name })), r))(1),
[]
);
console.log(result);
All of the other answers are valid, and are mostly more efficient and easier than mine. However, my answer is one of the easiest to understand.
My code uses Spread Syntax (...) to create the big array, but all that does is combines the arrays. Then, I use a .forEach() loop to loop through the array, and redefine the id. Then I incremented the id variable, so that the id's were in order.
const arr1 = [{id: 1, name: 'Jay'}, {id: 2, name: 'Kay'}];
const arr2 = [{id: 1, name: 'Pete'}, {id: 2, name: 'Liam'}];
const arr3 = [{id: 1, name: 'Baby'}, {id: 2, name: 'Neeson'}, {id: 3, name: 'Kobe'}];
let id = 1;
const bigArray = [...arr1, ...arr2, ...arr3];
bigArray.forEach(e => {
e.id = id;
id++;
});
console.log(bigArray);
You can use Array.from and spread
const arr1 = [{id: 1, name: 'Jay'}, {id: 2, name: 'Kay'}];
const arr2 = [{id: 1, name: 'Pete'}, {id: 2, name: 'Liam'}];
const arr3 = [{id: 1, name: 'Baby'}, {id: 2, name: 'Neeson'}, {id: 3, name: 'Kobe'}];
var result = Array.from([...arr1, ...arr2, ...arr3], ({name}, i)=>{ return {id: i + 1, name} });
console.log(result);
You can use reduce() map() and Spread Syntax.
Pass an array of all the arrays you want to merge to function
Flat that array using spread operator.
Then use reduce() to convert all the arrays to single dimensional array.
At last use map() and set it id property to index + 1
const arr1 = [{id: 1, name: 'Jay'}, {id: 2, name: 'Kay'}];
const arr2 = [{id: 1, name: 'Pete'}, {id: 2, name: 'Liam'}];
const arr3 = [{id: 1, name: 'Baby'}, {id: 2, name: 'Neeson'}, {id: 3, name: 'Kobe'}];
function merge(arrays){
return [...arrays].reduce((ac,a) => [...ac,...a],[]).map((x,i) => ({...x,id:i+1}));
}
console.log(merge([arr1,arr2,arr3]));

Add unique objects to array of objects in Javascript

I have arrays of objects that look like this:
const array1 = [{id: 1, name: "John"}, {id: 2, name: "Mary"}]
const array2 = [{id: 1, name: "John"}, {id: 3, name: "Phil"}, {id: 4, name: "Sarah"}]
How can I add unique objects from array2 to array1 so it looks like this:
const array1 = [{id: 1, name: "John"}, {id: 2, name: "Mary"}, {id: 3, name: "Phil"}, {id: 4, name: "Sarah"}]
Lodash implementations are permitted. Thanks a lot.
You can use _.unionBy() function to merge unique objects from arrays.
const array1 = [{id: 1, name: "John"}, {id: 2, name: "Mary"}];
const array2 = [{id: 1, name: "John"}, {id: 3, name: "Phil"}, {id: 4, name: "Sarah"}];
console.log(_.unionBy(array1, array2, 'id'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Using native array functions you can get the desired result as follows:
Concat both arrays first using .concat()
Use .reduce() to create the resultant object having ids as keys and values as relevant object. If already added an object then skip the others with same ids.
Use Object.values() to get an array of the objects from the resultant object.
Demo:
const array1 = [{id: 1, name: "John"}, {id: 2, name: "Mary"}],
array2 = [{id: 1, name: "John"}, {id: 3, name: "Phil"}, {id: 4, name: "Sarah"}];
const result = Object.values(
array1.concat(array2).reduce((r, c) => (r[c.id] = r[c.id] || c, r), {})
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can also do it in one line via native Map object and reduce:
const arr1 = [{id: 1, name: "John"}, {id: 2, name: "Mary"}]
const arr2 = [{id: 1, name: "John"}, {id: 3, name: "Phil"}, {id: 4, name: "Sarah"}]
const result = [...[...arr1, ...arr2]
.reduce((r, c) => (r.set(c.id, c), r), new Map()).values()]
console.log(result)

Merging of two arrays with conditions without using lodash

I am facing problem to merge the two arrays. I have two arrays of objects first is prev having old values and another with updated values. I would like to have result array with all the objects of prev array with its updated value in array next, and also have objects in next array.
Example:
var prev = [{id: 1, val: 'abc'}, {id: 2, val: 'pqr'}];
var next = [{id: 1, val: 'nextVal'}, {id: 3, val: 'xyz'}];
expected
mergeOutput = [
{id: 1, val: 'nextVal'}, // value is updated
{id: 2, val: 'pqr'},
{id: 3, val: 'xyz'}
]
Note: Array order do not matter.
You can use Map() to merge array.
var prev = [{id: 1, val: 'abc'}, {id: 2, val: 'pqr'}];
var next = [{id: 1, val: 'nextVal'}, {id: 3, val: 'xyz'}];
var hash = new Map();
prev.concat(next).forEach(function(obj) {
hash.set(obj.id, Object.assign(hash.get(obj.id) || {}, obj))
});
var mergedArray = Array.from(hash.values());
console.log(mergedArray);
Source : StackOverflow

Filter the original array of objects by array of ids

I have two arrays:
array a:
var a = [
{
id: 1,
name: 'a'
},
{
id: 2,
name: 'b'
},
{
id: 3,
name: 'c'
}
];
array ids:
var ids = [1];
I want to array a filtered by array ids, result i wanted:
var a = [
{
id: 1,
name: 'a'
}
];
The most important thing is i want the change on the original array, rather than return a new array.
underscore solution is better:)
You can use .filter
a = a.filter(function(el){
return ~ids.indexOf(el.id)
});
// should give you [{id: 1, name: 'a'}]
Today I tried to solve similar task (filtering the original array of objects without creating a new array) and this is what I came up with:
const a = [{ id: 1, name: 'a'}, { id: 2, name: 'b'}, { id: 3, name: 'c'}];
const ids = [1];
Array.from(Array(a.length).keys()).reverse().forEach(index =>
!ids.some(id => id === a[index].id) && a.splice(index, 1)
);
console.log(a); // [{ id: 1, name: 'a'}]
The point is that we need to loop back through the original array to be able to use Array.prototype.splice, but I didn't want the for-loop, I wanted to have ES6 one-liner. And Array.from(Array(a.length).keys()).reverse() gives me a list of reversed indexes of the original array. Then I want to splice the original array by current index only if the corresponding item's id is not present in the ids array.

Compare the elements of two arrays by Id and remove the elements from the one array that are not presented in the other

I have two arrays of objects like this:
var arr1 = [{Id: 1, Name: "Test1"}, {Id: 2, Name: "Test2"}, {Id: 3, Name: "Test3"}, {Id: 4, Name: "Test4"}]
var arr2 = [{Id: 1, Name: "Test1"}, {Id: 3, Name: "Test3"}]
I need to compare the elements of the two arrays by Id and remove the elements from arr1 that are not presented in arr2 ( does not have element with that Id). How can I do this ?
var res = arr1.filter(function(o) {
return arr2.some(function(o2) {
return o.Id === o2.Id;
})
});
shim, shim, shim.
You can use a function that accepts any number of arrays, and returns only the items that are present in all of them.
function compare() {
let arr = [...arguments];
return arr.shift().filter( y =>
arr.every( x => x.some( j => j.Id === y.Id) )
)
}
var arr1 = [{Id: 1, Name: "Test1"}, {Id: 2, Name: "Test2"}, {Id: 3, Name: "Test3"}, {Id: 4, Name: "Test4"}];
var arr2 = [{Id: 1, Name: "Test1"}, {Id: 3, Name: "Test3"}, {Id: 30, Name: "Test3"}];
var arr3 = [{Id: 1, Name: "Test1"}, {Id: 6, Name: "Test3"}, {Id: 30, Name: "Test3"}];
var new_arr = compare(arr1, arr2, arr3);
console.log(new_arr);
function compare() {
let arr = [...arguments]
return arr.shift().filter( y =>
arr.every( x => x.some( j => j.Id === y.Id) )
)
}
Making use of a hash (a Set) will give a performance gain:
var arr1 = [{Id: 1, Name: "Test1"}, {Id: 2, Name: "Test2"},
{Id: 3, Name: "Test3"}, {Id: 4, Name: "Test4"}];
var arr2 = [{Id: 1, Name: "Test1"}, {Id: 3, Name: "Test3"}];
arr1 = arr1.filter(function (el) {
return this.has(el.Id);
}, new Set(arr2.map(el => el.Id)));
console.log(arr1);
A new Set is created that gets the Id values from arr2:
"1","3"
That Set is passed as the thisArg to filter, so that within the filter callback it is available as this.

Categories

Resources