I have an array like
vendors = [{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
} // and so on...
];
How do I check this array to see if "Magenic" exists? I don't want to loop, unless I have to. I'm working with potentially a couple thousand records.
This question is related to
javascript
arrays
May be too late, but javascript array has two methods some
and every
method that returns a boolean and can help you achieve this.
I think some
would be most appropriate for what you intend to achieve.
vendors.some( vendor => vendor['Name'] !== 'Magenic' )
Some validates that any of the objects in the array satisfies the given condition.
vendors.every( vendor => vendor['Name'] !== 'Magenic' )
Every validates that all the objects in the array satisfies the given condition.
Unless you want to restructure it like this:
vendors = {
Magenic: {
Name: 'Magenic',
ID: 'ABC'
},
Microsoft: {
Name: 'Microsoft',
ID: 'DEF'
} and so on...
};
to which you can do if(vendors.Magnetic)
You will have to loop
As per ECMAScript 6 specification, you can use findIndex
.
const magenicIndex = vendors.findIndex(vendor => vendor.Name === 'Magenic');
magenicIndex
will hold either 0
(which is the index in the array) or -1
if it wasn't found.
No need to reinvent the wheel loop, at least not explicitly (using arrow functions, modern browsers only):
if (vendors.filter(e => e.Name === 'Magenic').length > 0) {
/* vendors contains the element we're looking for */
}
or, better yet:
if (vendors.some(e => e.Name === 'Magenic')) {
/* vendors contains the element we're looking for */
}
EDIT: If you need compatibility with lousy browsers then your best bet is:
if (vendors.filter(function(e) { return e.Name === 'Magenic'; }).length > 0) {
/* vendors contains the element we're looking for */
}
Here's the way I'd do it
const found = vendors.some(item => item.Name === 'Magenic');
array.some()
method checks if there is at least one value in an array that matches criteria and returns a boolean.
From here on you can go with:
if (found) {
// do something
} else {
// do something else
}
JS Offers array functions which allow you to achieve this relatively easily. They are the following:
Array.prototype.filter
: Takes a callback function which is a test, the array is then iterated over with is callback and filtered according to this callback. A new filtered array is returned.Array.prototype.some
: Takes a callback function which is a test, the array is then iterated over with is callback and if any element passes the test, the boolean true is returned. Otherwise false is returnedThe specifics are best explained via an example:
vendors = [_x000D_
{_x000D_
Name: 'Magenic',_x000D_
ID: 'ABC'_x000D_
},_x000D_
{_x000D_
Name: 'Microsoft',_x000D_
ID: 'DEF'_x000D_
} //and so on goes array... _x000D_
];_x000D_
_x000D_
// filter returns a new array, we instantly check if the length _x000D_
// is longer than zero of this newly created array_x000D_
if (vendors.filter(company => company.Name === 'Magenic').length ) {_x000D_
console.log('I contain Magenic');_x000D_
}_x000D_
_x000D_
// some would be a better option then filter since it directly returns a boolean_x000D_
if (vendors.some(company => company.Name === 'Magenic')) {_x000D_
console.log('I also contain Magenic');_x000D_
}
_x000D_
These 2 function are ES6
function, not all browsers might support them. To overcome this you can use a polyfill. Here is the polyfill for Array.prototype.some
(from MDN):
if (!Array.prototype.some) {_x000D_
Array.prototype.some = function(fun, thisArg) {_x000D_
'use strict';_x000D_
_x000D_
if (this == null) {_x000D_
throw new TypeError('Array.prototype.some called on null or undefined');_x000D_
}_x000D_
_x000D_
if (typeof fun !== 'function') {_x000D_
throw new TypeError();_x000D_
}_x000D_
_x000D_
var t = Object(this);_x000D_
var len = t.length >>> 0;_x000D_
_x000D_
for (var i = 0; i < len; i++) {_x000D_
if (i in t && fun.call(thisArg, t[i], i, t)) {_x000D_
return true;_x000D_
}_x000D_
}_x000D_
_x000D_
return false;_x000D_
};_x000D_
}
_x000D_
To compare one object to another, I combine a for in loop (used to loop through objects) and some(). You do not have to worry about an array going out of bounds etc, so that saves some code. Documentation on .some can be found here
var productList = [{id: 'text3'}, {id: 'text2'}, {id: 'text4', product: 'Shampoo'}]; // Example of selected products
var theDatabaseList = [{id: 'text1'}, {id: 'text2'},{id: 'text3'},{id:'text4', product: 'shampoo'}];
var objectsFound = [];
for(let objectNumber in productList){
var currentId = productList[objectNumber].id;
if (theDatabaseList.some(obj => obj.id === currentId)) {
// Do what you need to do with the matching value here
objectsFound.push(currentId);
}
}
console.log(objectsFound);
An alternative way I compare one object to another is to use a nested for loop with Object.keys().length to get the amount of objects in the array. Code below:
var productList = [{id: 'text3'}, {id: 'text2'}, {id: 'text4', product: 'Shampoo'}]; // Example of selected products
var theDatabaseList = [{id: 'text1'}, {id: 'text2'},{id: 'text3'},{id:'text4', product: 'shampoo'}];
var objectsFound = [];
for(var i = 0; i < Object.keys(productList).length; i++){
for(var j = 0; j < Object.keys(theDatabaseList).length; j++){
if(productList[i].id === theDatabaseList[j].id){
objectsFound.push(productList[i].id);
}
}
}
console.log(objectsFound);
To answer your exact question, if are just searching for a value in an object, you can use a single for in loop.
var vendors = [
{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
}
];
for(var ojectNumbers in vendors){
if(vendors[ojectNumbers].Name === 'Magenic'){
console.log('object contains Magenic');
}
}
You can use lodash. If lodash library is too heavy for your application consider chunking out unnecessary function not used.
let newArray = filter(_this.props.ArrayOne, function(item) {
return find(_this.props.ArrayTwo, {"speciesId": item.speciesId});
});
This is just one way to do this. Another one can be:
var newArray= [];
_.filter(ArrayOne, function(item) {
return AllSpecies.forEach(function(cItem){
if (cItem.speciesId == item.speciesId){
newArray.push(item);
}
})
});
console.log(arr);
The above example can also be rewritten without using any libraries like:
var newArray= [];
ArrayOne.filter(function(item) {
return ArrayTwo.forEach(function(cItem){
if (cItem.speciesId == item.speciesId){
newArray.push(item);
}
})
});
console.log(arr);
Hope my answer helps.
The accepted answer still works but now we have an ECMAScript 6 native method [Array.find][1]
to achieve the same effect.
Quoting MDN:
The find() method returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.
var arr = [];
var item = {
id: '21',
step: 'step2',
label: 'Banana',
price: '19$'
};
arr.push(item);
/* note : data is the actual object that matched search criteria
or undefined if nothing matched */
var data = arr.find( function( ele ) {
return ele.id === '21';
} );
if( data ) {
console.log( 'found' );
console.log(data); // This is entire object i.e. `item` not boolean
}
See my jsfiddle link There is a polyfill for IE provided by mozilla
Many answers here are good and pretty easy. But if your array of object is having a fixed set of value then you can use below trick:
Map all the name in a object.
vendors = [
{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
}
];
var dirtyObj = {}
for(var count=0;count<vendors.length;count++){
dirtyObj[vendors[count].Name] = true //or assign which gives you true.
}
Now this dirtyObj you can use again and again without any loop.
if(dirtyObj[vendor.Name]){
console.log("Hey! I am available.");
}
You can use includes
from the Ramda library:
i.e:
R.includes({ name: 'Fred' }, [{ name: 'Fred' }]); //=> true
You can try this its work for me.
const _ = require('lodash');
var arr = [
{
name: 'Jack',
id: 1
},
{
name: 'Gabriel',
id: 2
},
{
name: 'John',
id: 3
}
]
function findValue(arr,value) {
return _.filter(arr, function (object) {
return object['name'].toLowerCase().indexOf(value.toLowerCase()) >= 0;
});
}
console.log(findValue(arr,'jack'))
//[ { name: 'Jack', id: 1 } ]
Correct me if i'm wrong..
i could have used forEach
method like this,
var found=false;
vendors.forEach(function(item){
if(item.name === "name"){
found=true;
}
});
Nowadays i'm used to it ,because of it simplicity and self explanatory word. Thank you.
I would rather go with regex.
If your code is as follows,
vendors = [
{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
}
];
I would recommend
/"Name":"Magenic"/.test(JSON.stringify(vendors))
You have to loop, there is no way around it.
function seekVendor(vendors, name) {
for (var i=0, l=vendors.length; i<l; i++) {
if (typeof vendors[i] == "object" && vendors[i].Name === name) {
return vendors[i];
}
}
}
Of course you could use a library like linq.js to make this more pleasing:
Enumerable.From(vendors).Where("$.Name == 'Magenic'").First();
(see jsFiddle for a demo)
I doubt that linq.js will be faster than a straight-forward loop, but it certainly is more flexible when things get a little more complicated.
You cannot without looking into the object really.
You probably should change your structure a little, like
vendors = {
Magenic: 'ABC',
Microsoft: 'DEF'
};
Then you can just use it like a lookup-hash.
vendors['Microsoft']; // 'DEF'
vendors['Apple']; // undefined
const VENDORS = [{ Name: 'Magenic', ID: 'ABC' }, { Name: 'Microsoft', ID: 'DEF' }];
console.log(_.some(VENDORS, ['Name', 'Magenic']));
_x000D_
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
_x000D_
if you're using jquery you can take advantage of grep to create array with all matching objects:
var results = $.grep(vendors, function (e) {
return e.Name == "Magenic";
});
and then use the results array:
for (var i=0, l=results.length; i<l; i++) {
console.log(results[i].ID);
}
No loop necessary. Three methods that come to mind:
Array.prototype.some()
This is the most exact answer for your question, i.e. "check if something exists", implying a bool result. This will be true if there are any 'Magenic' objects, false otherwise:
let hasMagenicVendor = vendors.some( vendor => vendor['Name'] === 'Magenic' )
Array.prototype.filter()
This will return an array of all 'Magenic' objects, even if there is only one (will return a one-element array):
let magenicVendors = vendors.filter( vendor => vendor['Name'] === 'Magenic' )
If you try to coerce this to a boolean, it will not work, as an empty array (no 'Magenic' objects) is still truthy. So just use magenicVendors.length
in your conditional.
Array.prototype.find()
This will return the first 'Magenic' object (or undefined
if there aren't any):
let magenicVendor = vendors.find( vendor => vendor['Name'] === 'Magenic' );
This coerces to a boolean okay (any object is truthy, undefined
is falsy).
Note: I'm using vendor["Name"] instead of vendor.Name because of the weird casing of the property names.
Note 2: No reason to use loose equality (==) instead of strict equality (===) when checking the name.
const check = vendors.find((item)=>item.Name==='Magenic')
console.log(check)
Try this code.
If the item or element is present then the output will show you that element. If it is not present then the output will be 'undefined'.
As the OP has asked the question if the key exists or not.
A more elegant solution that will return boolean using ES6 reduce function can be
const magenicVendorExists = vendors.reduce((accumulator, vendor) => (accumulator||vendor.Name === "Magenic"), false);
Note: The initial parameter of reduce is a false
and if the array has the key it will return true.
Hope it helps for better and cleaner code implementation
Alternatively you can do:
const find = (key, needle) => return !!~vendors.findIndex(v => (v[key] === needle));
My approach to solving this problem is to use ES6 and creating a function that does the check for us. The benefit of this function is that it can be reusable through out your project to check any array of objects given the key
and the value
to check.
ENOUGH TALK, LET'S SEE THE CODE
Array
const ceos = [
{
name: "Jeff Bezos",
company: "Amazon"
},
{
name: "Mark Zuckerberg",
company: "Facebook"
},
{
name: "Tim Cook",
company: "Apple"
}
];
Function
const arrayIncludesInObj = (arr, key, valueToCheck) => {
return arr.some(value => value[key] === valueToCheck);
}
Call/Usage
const found = arrayIncludesInObj(ceos, "name", "Tim Cook"); // true
const found = arrayIncludesInObj(ceos, "name", "Tim Bezos"); // false
var without2 = (arr, args) => arr.filter(v => v.id !== args.id);
Example:
without2([{id:1},{id:1},{id:2}],{id:2})
Result: without2([{id:1},{id:1},{id:2}],{id:2})
const a = [{one:2},{two:2},{two:4}]
const b = a.filter(val => "two" in val).length;
if (b) {
...
}
Source: Stackoverflow.com