How to check if value existed in array or not? - javascript

I dont want to push duplicate values into selectedOwners, so in below code user is selecting owner if owner already existed in selectedOwners array i dont want to push , How can i check that to avoid duplicate values in an array ?
ctrl.js
var selectedOwners = [];
$scope.addProcessOwner = function(dataItem){
var selectedOwner = {
fullName: dataItem.fullName,
workerKey: dataItem.workerKey
}
if(selectedOwners.indexOf(selectedOwner) !== -1) {
selectedOwners.push(selectedOwner);
}
console.log('WORKER DATA',selectedOwners);
}

You can use Array.prototype.some method
The some() method tests whether some element in the array passes the test implemented by the provided function.
var isExists = function(e) {
if (e.fullName == selectedOwner.fullName
&& e.workerKey == selectedOwner.workerKey) {
return true;
}
}
if (!selectedOwners.some(isExists)) {
selectedOwners.push(selectedOwner);
}

The use of Array.indexOf is obvious for simple types like strings and numbers.
However, when you are looking for an object, you have to pass the exact same object. A different object with all the same properties and values will still not work. Think of the array as containing pointers to the objects and you must look for the same pointer.
Instead you will need to write your own method to compare the owners for equality and loop through the array doing this check.

Try wrapping your "if" logic in a for-loop .
Example
//Following code loops through array and check for already existing value
for(var i = 0; i < selectedOwners.length; i++){
if(selectedOwners.indexOf(selectedOwner) !== -1) {
selectedOwners.push(selectedOwner);
}
}

Related

How to calculate the number of objects I get from the loop Javascript

I filtered my set of users(array) with if(elem.id_verified). I now get 77 users objecta. I just want to take the number of these objects. I tried with console.log(this.numOfunverifiedUsers.length) but i get 77 underfined. My question is how to assemble all objects and get that number. Maybe my logic is going in the wrong direction.
this.users=response.data.users
this.numOfunverifiedUsers = []
this.users.forEach(elem => {
if (elem.id_verified === 0) {
this.numOfunverifiedUsers = elem
console.log(this.numOfunverifiedUsers.length)
}
})
this.numOfunverifiedUsers.push(elem)
Push the element in array.
this.numOfunverifiedUsers = elem , replace it with above
This should work too:
console.log(this.users.filter(function (val) {
return val.id_verified === 0
}).length)
filter items that are id_verified === 0 and count their length.
I think would be better you build that list with a filter:
this.numOfunverifiedUsers = this.users.filter(
user => user.id_verified === 0
);
console.log(this.numOfunverifiedUsers);
console.log(this.numOfunverifiedUsers.length);
If you want to read about filter: Filter method
With this.numOfunverifiedUsers = elem, you are assigning 'elem' to an array reference. As a result, you get exceptions which make the '=' operator return the undefined primitive type (as the result of function errors; see undefined - JavaScript | MDN). What you want to do is either add the element iteratively into the array the "old way", via element assigning, or just use the OOP way via the push method. The former wouldn't require a count function, as you can do something like that:
var count = 0; //outside the forEach
...
if (elem.id_verified === 0) {
{
this.numOfunverifiedUsers[count++]=elem
console.log(count)
}
...
However, as others pointed out, using a filter makes the code much more clean and readable
This would work better with the use of a Filter
console.log(this.users.filter(function (val) {
return val.id_verified === 0
}).length)
filter items that are id_verified === 0 and count their length.

Check the object already exists in array in Vue.js

I have a data:
data: function() {
return {
conversations:
[
]
}
}
I'm getting my data from response object: response.data.conversation
Is there a way to check this.conversations already contains response.data.conversation?
To build on your answer, if you're already using underscore or lodash you can use its _.any()/_.some() function:
var exists = _.any(this.conversations, function(conversation) {
return _.isEqual(conversation, response.data.conversation);
})
You can also use Array.prototype.some to do the same kind of thing:
var exists = this.conversations.some(function(conversation) {
return _.isEqual(conversation, response.data.conversation);
})
The benefits of these over your solution is that they'll return as soon as they find a match (instead of iterating through the whole array), though you could easily update your code to break out of the loop early.
Also, while _.isEqual() is cool, you might be able to get away with some simple property comparisons (if your objects are flat enough or, even better, you have a key that uniquely identifies a conversation) to determine if two objects are equivalent:
var exists = this.conversations.some(function(conversation) {
return conversation.id === response.data.conversation.id;
})
I figured it out:
Used underscore.js.
Iterate trought all objects in array and compare them with _.isEqual(a,b)
function
var count=0;
for(var i=0; i<this.conversations.length; i++ ) {
if(_.isEqual(this.conversations[i], response.data.conversation)) {
count++;
}
}
Then check the value of count variable:
if (count == 0) {
//Add element to array
this.conversations.push(response.data.conversation);
} else {
console.warn('exists');
}

Adding and Removing Values from JavaScript Array

I have a JavaScript array of numbers. My array is defined like this:
var customerIds = [];
I have a function that is responsible for inserting and removing ids to/from this array. Basically, my function looks like this:
function addOrRemove(shouldAdd, customerId) {
if (shouldAdd) {
if (customerIds.contains(customerId) === false) {
customerIds.push(customerId);
}
} else {
customerIds.remove(customerId);
}
}
This function is basically pseudocode. A JavaScript array does not have a contains or remove function. My question is, is there any elegant way of tackling this problem? The best I can come up with is always looping through the array myself and tracking the index of the first item found.
Thank you for any insights you can provide.
The contains can be achieved with Array.prototype.indexOf, like this
if (customerIds.indexOf(customerId) === -1) {
indexOf function returns -1, if it couldn't find the parameter in the array, otherwise the first index of the match. So, if the result is -1, it means that customerIds doesn't contain customerId.
The remove can be achieved with Array.prototype.indexOf and Array.prototype.splice, like this
var index = customerIds.indexOf(customerId);
if (index !== -1) {
customerIds.splice(index, 1);
}
Similarly, indexOf function returns -1, if it couldn't find the parameter in the array, otherwise the first index of the match. So, if the result is -1, we skip deleteing, otherwise splice 1 element starting from the position index.
You can extend the Array method like below after that you are free to use 'contains' and 'remove'
if (!Array.contains)
Array.prototype.contains = function(a) {
for (var i in this) {
if (this[i] == a) return true;
}
return false
}
if (!Array.remove)
Array.prototype.remove = function(a) {
for (var i in this) {
if (this[i] == a) {
this.splice(i, 1);
}
}
}
Use indexOf and splice
function addOrRemove(shouldAdd, customerId) {
if (shouldAdd) {
if (customerIds.indexOf(customerId) == -1) {
customerIds.push(customerId);
}
} else {
var index = customerIds.indexOf(customerId)
customerIds.splice(index, 1);
}
}
You could definitely use the splice and indexOf as stated by #thefourtheye, yet I would like to provide another approach.
Instead of using an array you could use an object.
var customerIds = {};
//This could also be stated as: var customerIds = new Object(); this is just shorthand
function addOrRemove(shouldAdd, customerId)
{
if(shouldAd)
{
if(!customerIds[customerId])
{
customerIds[customerId] = new Object();
customerIds[customerId].enabled = true;
}
}
else
{
if(customerIds[customerId])
{
customerIds[customerId].enabled = false;
}
}
}
You now can query against the customerIds object for a specific customerId
if(customerIds[customerId].enabled)
Using this method not only provides you with the capability of attaching multiple attributes to a given customerId, but also allows you to keep records of all customerIds after disabling (removing).
Unfortunately, in order to truely remove the customerId, you would need to loop through the object and append each property of the object to a new object except for the one you do not want. The function would look like this:
function removeId(customerId)
{
var n_customerIds = new Object();
for(var key in customerIds)
{
if(key != customerId)
{
n_customerIds[key] = customerIds[key];
}
}
customerIds = n_customerIds;
}
In no way am I stating that this would be the proper approach for your implementation, but I am just providing another method of achieving your goal. There are many equivalent ways to solve your dilemma, and it is solely decided by you which method will best suit your projects functionality. I have personally used this method in many projects, as well as I have used the methods posted by others in many other projects. Each method has their pros and cons.
If you do wish to use this method, I would only suggest doing so if you are not collecting many customerIds and do want a lot of customerData per each customerId, or, if you are collecting many customerIds and do not want a lot of customerData per each customerId. If you store a lot of customerData for a lot of customerIds, you will consume a very large amount of memory.

Javascript: Determine if all of the elements in the array are keys in the object

I am trying to figure out if all of the elements in an array are keys in the object.
var obj = { name: 'Computer', cost: '$1,000' };
var myArray = [ 'name', 'cost', 'bio' ]; //another example would be var myArray = [];
for(var x = 0; x < myArray.length; x++){
if (myArray[x] in obj)
{
return true;
}
}
How can I check if all of the elements in an array are keys in the object?
Do it the other way around. If you find someone in the array who is NOT in the object then you return false. If you reach the end of the loop then you return true because all the keys were in the object.
Depending on what you want, this might do the trick:
function hasKeys(obj, keys) {
for (var i=0; i != keys.length; ++i) {
if (!(keys[i] in obj))
return false;
}
return true;
};
One subtlety you need to ask yourself: do you want to know if the object has the keys directly (i.e. not somewhere in its prototype stack?) If so, then replace keys[i] in obj with obj.hasOwnProperty(keys[i])
function hasKeys(obj, keys) {
return keys.every(Object.prototype.hasOwnProperty.bind(obj));
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every states, "The every method executes the provided callback function once for each element present in the array until it finds one where callback returns a falsy value (a value that becomes false when converted to a Boolean). If such an element is found, the every method immediately returns false. Otherwise, if callback returned a true value for all elements, every will return true. callback is invoked only for indexes of the array which have assigned values; it is not invoked for indexes which have been deleted or which have never been assigned values" (emphasis mine).
Array.some() makes for a clean solution.
// object in question
var obj = { ... };
// keys that need to be present in the object
var keys = [ ... ];
// iterate through the whitelist until we find a key that doesn't exist in the object. If all exist, that means Array.some() is false.
var valid = !keys.some(function(key) {
return !obj.hasOwnProperty(key);
});
An alternative solution would be using a similar concept, but with Array.every(). It is to note that this will generally be slower because it always has to touch every element in the whitelist.
// iterate through the whitelist, making sure the object has each key.
var valid = keys.every(obj.hasOwnProperty);
This problem can be expressed in terms of set inclusion: does the set of property keys completely include the array of required keys? So we can write it as
includes(Object.keys(obj), arr)
So now we just need to write includes.
function includes(arr1, arr2) {
return arr2.every(function(key) {
return contains(arr1, key);
}
}
For contains, we could use Underscore's _.contains, or just write it ourselves:
function contains(arr, val) {
return arr.indexOf(val) !== -1;
}
If we are interested in conciseness at the possible expense of readability, we could shorten our definition of includes to use Function#bind instead of the anonymous function:
function includes(arr1, arr2) {
return arr2.every(contains.bind(0, arr1));
}
Now we have functions we can use for other things, instead of mixing up the two different aspects of the problem--the keys of an object, and set inclusion. If we really want to write an all-in-one function, it becomes the somewhat more readable:
function hasMany(obj, arr) {
return arr.every(_.contains.bind(0, Object.keys(obj));
}
If we want more readability, like we were writing a novel:
function object_has_required_keys(object, required_keys) {
var object_keys = Object.keys(object);
function key_is_present(key) {
return object_keys.indexOf(key) !== -1;
}
return required_keys.every(key_is_present);
}
Underscore's _.intersection
If we're lazy (or smart), we could use Underscore's _.intersection to implement includes:
function includes(arr1, arr2) {
return _.intersection(arr1, arr2).length === arr2.length;
}
The idea is to take the intersection, and if the first array includes the second entirely, then the intersection will contain all the elements of the second array, which we can check by comparing their lengths.
Using ES6 sets
Thinking ahead to ES6, we could implement include using its sets, which ought to be faster:
function includes(arr1, arr2) {
var set = new Set(arr1);
return arr2.every(Set.prototype.has.bind(set));
}

Why does the following JavaScript test show the element as not belonging to the array?

The code is very simple and I would be expecting true however it returns false
var markets = ["AB", "CD"];
console.log("AB" in markets);
I think you're meaning if (markets.indexOf('AB') !== -1). in essentially checks if the test is a property of the object, not if an element is contained within the array.
For more information, look at Array.indexOf vs. the in operator.
Because in looks up property names, not values. Your property names are the array indices.
From MDN's page on the in operator:
The in operator returns true if the specified property is in the specified object.
prop A string or numeric expression representing a property name or array index
Note a property name or array index. The in operator does not search for property values, but for property names. In this case, the property names are 0 and 1, so 0 in markets will return true.
You should use indexOf, in browsers that support it, and shim it in those that don't.
Because in is meant for objects, not arrays. If you want to reliably do this you have to search through each element in the array:
for( var i=0, l=markets.length; i<l; i++ ){
if( markets[i] === 'AB' ){
// do something
}
}
The following will work, which is what you're thinking:
var markets = { AB: 1, CD: 1 };
console.log( "AB" in markets );
In only works when you are using an object, not an array. So this will work:
var markets = {
AB: 'AB',
CD: 'CD'
};
'AB' in markets; // true
As said in won't help you in this case.
I guess you'll have to write a searching function.
Here's one:
function inArray(ArrObj, Search){
var exists = false;
for (var i = 0; i < ArrObj.length; i++){
if (ArrObj[i] == Search){
return true;
var exists = true;
break;
}
else if ((i == (ArrObj.length - 1)) && (!exists)){
if (ArrObj[i] != Search){
return false;
}
}
}
}
I think you want something like this, console.log(markets[0]);

Categories

Resources