Best way to find if an object exists between 2 arrays - javascript

The following method seems a little naive to me so I am wondering if there is a better way to do this. 2 arrays are involved and they contain objects which I have to compare by a certain property:
function exists(objArray, id) {
var isFound = false;
objArray.forEach(obj => {
if (obj.Id == id)
isFound = true;
});
return isFound;
}
var array1, array2;
array1.forEach(obj => exists(array2, obj.Id));

Use .some instead.
const exists = (objArray, id) => objArray.some(obj => obj.Id === id);
(I'd highly recommend using strict equality === and not sloppy equality if at all possible)

You can use lodash's differenceWith by passing a comparator function to check if two arrays have a common object.
comparator(obj1, obj2){
return obj1.id !== obj2.id;
}
let arr1 = [{id: 1}]
let arr2 = [{id: 2}]
_.differenceWith(arr1, arr2, comparator)
It returns an empty array if no matching elements, else returns the object with matching id of first array

Related

How to check if values in array is present in object key of object array

I want to check if values in one array is present in object key of object array.
For example: arr = ["id1", "id2"]
objectArr = [{id: "id1"}]
I want to throw not found error in this case when id2 is not present in id of object array.
Help of any kind would be appreciated!
You can use filter and some for that:
var objectArr = [{id: "id1"}, {id: "id3"}]
var arr1 = ["id1", "id2"];
const notFounds = arr1.filter(el => !objectArr.some(obj => obj.id === el ));
console.log(notFounds); // ["id2"]
JS Array some:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some
JS Array filter:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
If You iterate over objectArr, You can get object fields in form of array with: Object.entries(your_object).
for (const obj of objectArr) {
for (const item of Object.entries(obj)) {
// where item is field in object
// now You can compare if item is in [id1,id2]
}
}
You can try something like this
var arr = ["id1", "id2", "id3", "id4"];
var n = arr.includes("id2"); //true
For an array of objects. If the id is unique in the array
var arr = [{id:"id1"},{id:"id2"},{id:"id3"},{id:"id4"}]
const found = arr.some(el => el.id === "id3") // true
EDIT: ran.t has a better answer that keeps track of which ids are not found.
It sounds like what you're looking for is .every() method. Which will allow you can check each element in the array passes a given condition.
You can combine this with the .some() method to check at least one object in the objectArr has id equal to your element
const allElementsFound = ["id1", "id2"].every(el => objectArr.some(obj => obj.id === el))
if(!allElementsFound) {
// throw error
}

Arrow function with conditionals not returning all elements of array

I have an array like the following: var arr = ['one', 'two', ['three', 'four']];
While trying to return each element by using the arrow function, it returns undefined as the third element, instead of the elements values. I've attempted to restructure it, but none of then return all the elements of both arrays. I could use a for loop, do the logic to push each element, but I want to understand and learn how to use arrow functions for cases like this.
arr.map(e => {
if(typeof(e) == "object"){
e.map(t => t)
} else{ return e; }
})
Will really appreciate some clarification in this matter. The expected result is an array like the following: ['one', 'two', 'three', 'four'].
Array.prototype.map() is not designed and implemented to flatten an array. Even if .map() did flatten an array e.map(t => t) is not returned from .map() callback function at the code at the question.
arr.map(e => {
if(typeof(e) == "object"){
e.map(t => t) // no value is `return`ed here
} else{ return e; }
})
There are a variety of approaches and Array methods that can be used to flatten an Array, including .flat(), .flatMap() and .concat(), e.g., see Merge/flatten an array of arrays in JavaScript?
To achieve expected result, use below option of using reduce to return all elements of array within array
var arr = ['one', 'two', ['three', 'four']];
console.log(arr.reduce((acc, v) => {
typeof(v) == 'object' ? acc.push(...v) : acc.push(v)
return acc
}, []))
codepen - https://codepen.io/nagasai/pen/NJKdKv

JavaScript or Lodash find objects by key

In an array of objects with diff keys, how do I find objects by key using ES6 or Lodash?
const arr = [{a:2}, {b:3}, {fred:10}]
I want the result to be:
=> [{a:2}, {fred:10}]
I don't want to use an omit style approach.
const filtered = arr.filter(obj => obj.hasOwnProperty("a") || obj.hasOwnProperty("fred"));
// or, if you have dynamic / lots of keys:
const keys = ["a", "fred"];
const filtered = arr.filter(obj => keys.some(key => obj.hasOwnProperty(key));
filter method will be useful. Create a function and pass an array of keys. Inside filter function check if the key is matching with the parameter array. If it passed then return that object
var orgObject = [{
a: 2
}, {
b: 3
}, {
fred: 10
}];
function searchByKey(keyNames) {
return orgObject.filter(function(item) {
for (var keys in item) {
if (keyNames.indexOf(keys) !== -1) {
return item
}
}
})
}
console.log(searchByKey(['a', 'fred']))
Basically you want all the objects from the array who have the fields a or fred. You can use the hasOwnProperty() on the objects while filtering.
_.filter(array, elem => elem.hasOwnProperty('a') || elem.hasOwnProperty('fred'));

easiest way to see if array has array? Javascript

the only way I can think to do this is to do something like:
for current array length,
for array to check length
if current array i === array to check i
true
Essentially I have the following:
arr = [[1,2], [0,3]];
When I want to add another array to this arrays: [1,2] I need to first see if it exists, if it does do not push it on to the array, if it doesn't then push it.
Is there some really simple, clean readable way to check if an array exists in an array of arrays before pushing it on to the list of elements?
Update:
it should be pretty simple, you have array:
arr = [[1,2], [0,3]];
You try and push:
[1,2]
Nothing happens.
You try and push: [4,6]. New array: [[1,2], [0,3], [4,6]];
Since the complexity is limited, a simple solution exists:
function maybePush(to, val) {
if(!to.some(function(curr) {
return curr.length !== val.length ||
curr.some(function(v, i) { return val[i] === v; });
})) {
to.push(val);
}
}
arr = [[1,2], [0,3]];
maybePush(arr, [1,2]);
maybePush(arr, [5,6]);
console.log(arr);
You'd probably want to add some guards, check that what you expect to be an array really is an array and so on (left out for clarity)...
The idea is simple, check if any of the values of the outer array is equal to the val array, using an iterative comparison.
If you know your array arr contains only integers and arrays, a simple check to see if the array matches the flattened array will indicate if the array contains inner arrays.
var arr = [1,2,3,[4,5],6];
if (JSON.stringify(arr) === JSON.stringify([].concat.apply([], arr))) {
// Does not contain an array
}
The snippet [].concat.apply([], arr) flattens the array arr.
Using underscore you can do this:
Initial approach:
var i = _.findIndex(arr, function (e) {
return (e.join(',') === arr_elem.join(','));
});
if (i === -1) {
arr.push(arr_elem);
}
EDIT Considering performance (Also read the comments here), it would be better to check array equality using a brute loop approach:
function arraysEqual(arr1, arr2) {
if(arr1.length !== arr2.length)
return false;
for(var i = arr1.length; i--;) {
if(arr1[i] !== arr2[i])
return false;
}
return true;
}
var i = _.findIndex(arr, function (e) {
return arraysEqual(arr_elem, e);
});
if (i === -1) {
arr.push(arr_elem);
}

Return all matching elements of an array of objects?

I have an array that consists of objects with two properties.
One property "value" is a number between 1 and 6.
The other property "id" is a number between 1 and 200.
How can I return the "id" property of all objects with "value" = 1 and write them to a new array?
You should invoke the Array.prototype.filter function there.
var filteredArray = YourArray.filter(function( obj ) {
return obj.value === 1;
});
.filter() requires you to return the desired condition. It will create a new array, based on the filtered results. If you further want to operate on that filtered Array, you could invoke more methods, like in your instance .map()
var filteredArray = YourArray.filter(function( obj ) {
return obj.value === 1;
}).map(function( obj ) {
return obj.id;
});
console.log( filteredArrays ); // a list of ids
... and somewhere in the near future, we can eventually use the Arrow functions of ES6, which makes this code even more beauty:
var filteredArray = YourArray.filter( obj => obj.value === 1 ).map( obj => obj.id );
Pure JS.... no filter/map functions, that are not available for IE < 9
var array = [
{id:10, value:2}, {id:11, value:1}, {id:12, value:3}, {id:13, value:1}
],
result = [];
for(key in array) { if (array[key].value == 1) result.push(array[key].id); }
You can use a combination of Array.prototype.filter and Array.prototype.map.
First, filter only values with value equal to 1.
arr.filter(function (obj) {
return obj.value === 1;
});
Then, you map existing collection to a new array, consisting only of id properties stored in filtered array. So the final code:
var newArr = arr.filter(function (obj) {
return obj.value === 1;
}).map(function (obj) {
return obj.id;
});
The good news is, it's easy, just write
[ for (obj of array) if (obj.value === 1) obj.id ]
The bad news is, it will some time before you can depend on all browsers to do this. It's from a new version of the language called "ES6". But you can try it right now in Firefox!!
for multiple items to be searched from an array into some array of objects, use this
let old = []
ao = [{}, {}], array of objects
let newlist = []
old.map(a => ao.find(x => x.Name == a)!==undefined? newlist.push(ao.find(x => x.Name == a)): null)

Categories

Resources