Trying to prevent duplicate values to be added to an array. - javascript

Having an issue with my project when it comes to adding a duplicate value to an array on a click event.
when I push the clicked item's value to the array openedCards.push(card); the code allows for multiple item values to be added to the array thus creating a matched value with a single item.
I have tried wrapping this code like so if ($.inArray(card, openedCards) < 0)openedCards.push(card); i see that the match class is no longer being added to matching pairs, or any values for that matter.
here is the Here is the jsfiddle

With vanilla javascript you can do this like the following:
if (array.indexOf(value) === -1) array.push(value);
Where array is your array of value's that you don't want duplicates of.
Or, you can use the following es6 syntax:
if (array.includes(value) === false) array.push(value);

I think you are running into issues with using object reference vs value
While obj and obj2 have same value for underlying properties, they both return different values to $.inArray
arr = [];
obj = {}; obj.A = 2;
arr.push(obj);
obj2 = {}; obj2.A = 2;
console.log($.inArray(obj, arr)); // 0
console.log($.inArray(obj2, arr)); // -1
In this case, I would recommend using some other property of card to check for availability within the array
function containsCard(card, list) {​
return list.some(function(elem) {
return elem.A === card.A
})
}
arr = [];
obj = {}; obj.A = 2;
arr.push(obj);
obj2 = {}; obj2.A = 2;
console.log(containsCard(obj, arr)); // true
console.log(containsCard(obj2, arr)); // true

You can just use $.inArray(), like:
if(!$.inArray(value, array))array.push(value);

Related

I have an issue with removing an object key with a for in loop

I'm using a for x in loop to check if a value is == to [] and if so remove the property using remove but it just does not seem to work.
const whosOnline = (a) => {
var obj = { online:[],
offline:[],
away:[] };
for(let i = 0; i < a.length; i++){
if(a[i].lastActivity > 10 && a[i].status == 'online'){obj.away.push(a[i].username)}
else if(a[i].status == 'offline'){obj.offline.push(a[i].username)}
else{obj.online.push(a[i].username)}
}
for(let x in obj){
console.log(obj[x])
if(obj[x] === []){delete obj[x]}}
return obj
}
you were close, however you also need to reference the array index for each object key value. Comments explaining this in the code below.
var obj = { online:[],
offline:[],
away:[] };
for(var x in obj){
if(!obj[x][0]){ // The 0 is the index inside the online array, next loop it will be the offline array and then the away array.
console.log('The array is empty');
// Do what you want to do now that it is empty
// This will continue to loop through and check the value of all the keys in the object.
}
}
console.log('done');
Good luck -
Mitch from
https://spangle.com.au
Using some debugging (simply testing if a console.log gets printed for instance) you find that your if-condition is never true.
This is because you test if an array equals a newly created empty array. This can never be the case, because objects are compared by object reference instead of value.
Instead you want to probably test to see if your array is empty by doing ‘if(obj[x].length===0)’ (or shorter: ‘if(!obj[x].length)’)

how to insert new object in node js array if key not exist

I want to create data structure like that.
Var ans =[{"b":[1,2]},{"g":[100,2]}]
I want to create a new object within list if key not exists in list ans.
Else if key exists in one object of ans list then I want to add new values into the object of ans list
For Example:
Example 1) new data c:{2000}
then
Var ans =[{"b":[1,2]},{"g":[100,2]},{c:[2000]}]
Example 2) new data g:{50}
then
Var ans =[{"b":[1,2]},{"g":[100,2,500]},{c:[2000]}]
I am a beginner in node js, understand array, object concept, but not getting exact logic!
Thanks!
You can try following:
Logic
Filter array based on key
Check if object with mentioned key exists or not.
If yes, push value to this array.
If not, create a dummy object and push this object to original array.
Correction, when you do .push({key: value}), key will be considered as string.
Alternates
If you are using ES6, .push({ [key] : value })
Create a dummy object var o = {}. Set key and value to it o[key] = value and push this object.
Optimisations
Instead of setting value like obj[key] = value, since we will be operating on arrays, try obj[key] = [].concat(value). This will enable you to pass value as number or array of values.
Instead of checking the existence of value in .filter, try Array.isArray to check if value exists and is of type array.
Custom function
function checkAndPush(array, key, value) {
var filteredList = array.filter(function(o) {
return Array.isArray(o[key]);
});
filteredList.length > 0 ? filteredList[0][key].push(value) : array.push({
[key]: [].concat(value)
});
return array;
}
var ans =[{"b":[1,2]},{"g":[100,2]}]
console.log(checkAndPush(ans, "c", [2,3]))
console.log(checkAndPush(ans, "c", 4));
Prototype function
Array.prototype.checkAndPush = function(key, value) {
var filteredList = this.filter(function(o) {
return Array.isArray(o[key]);
});
var dummy = {}
dummy[key] = [].concat(value)
filteredList.length > 0 ? filteredList[0][key].push(value) : this.push(dummy);
// or ES6: this.push({ [key]: [].concat(value) })
return this;
}
var ans =[{"b":[1,2]},{"g":[100,2]}]
console.log(ans.checkAndPush("c", [2,3]))
console.log(ans.checkAndPush("c", 4));
If you are dealing with objects as your values
ans[key] = ans[key] || []
ans[key].push(value)
Note, this works because your values will be an array. If they could be primatives then you would use hasOwnProperty to check.
if (ans.hasOwnProperty(key)) {
// Add this to your key somehow
} else {
// initialize the key with your value
}
Node.js is nothing but a library built on javascript. You can do anything using javascript type of progmming. However push and pop method should be able to help you to deal with nodejs array.
ans[key].push(value)

How to access property in object according to array

so i have an array like this:
var arr=[one, lol];
and an object like this
var obj={
one:{
lol:11234
}
}
How do I make it so if i do obj[lol] then it will print out 11234? Keep in mind I don't know how long the array is and answers like console.log(obj[one][lol]) doesn't work. Thanks in advance.
You can store the previous property's value (initially obj) and continue to loop until end of array like so:
var arr = ['one', 'two', 'three'];
var obj = {
one: {
two: {
three: 11234
}
}
}
var currentProp = obj;
for(var i = 0; i < arr.length; i++) {
currentProp = currentProp[arr[i]];
}
console.log(currentProp);
The above code will start at the object obj, then loop until the array's length, and reassign currentProp to the next property in the array as it goes. In this case, this is what it does:
First iteration, access obj[arr[0]], which is one, and assign it to currentProp
Second iteration, access obj[arr[0]][arr[1]] or one[arr[1]], which is two, and assign it to currentProp
Third iteration, access obj[arr[0]][arr[1]][arr[2]] or two[arr[2]], which is three, and assign it to currentProp. Loop then terminates as it has reached end of the list.
In the end, the value of the last property will be in currentProp, and will correctly output 11234.
You need to try like this :
obj["one"]["lol"]
JsFiddle : https://jsfiddle.net/3we2ohy6/1/
Since you are just looking up a property value it is simpler to do:
console.log(obj.one.lol);
Doing it using the square brackets the way you have it JS thinks both the one and LOL are variables. Unless you wrap them in quotes.
console.log(obj['one']['lol');
You will not get to the value you are looking for the way you are doing it unless you create a function that either restructures the obj object or you feed it the obj.one as a property.
You could use Array#reduce, because this returns the object you need, without keeping a reference outside.
function set(object, path, value) {
var last = path.pop();
path.reduce(function (o, k) {
return o[k] = o[k] || {};
}, object)[last] = value;
}
var obj = {};
set(obj, ['one', 'lol'], '11234');
console.log(obj);

Remove false values in object

The problem that I'm facing is -removing the values in the onject that has the property false
Here is the object
var myObj={105:true,183:false,108:true,106:false}
I'm able to get the values in an array by using the following logic:
Object.keys(myObj) gives ["105","183","108","106"]
But I need a way to remove the values that have the property false and generate as ["105",108"].Can you help me out ?
You have the keys of the object in an array. Run filter over it.
var myObj={105:true,183:false,108:true,106:false};
var result = Object.keys(myObj).filter(function(x) {
return myObj[x] !== false;
});
// result = ["105", "108"]
I've just created a solution to your problem on JSBin: Working Demo
Please find below the code:
var myObj={105:true,183:false,108:true,106:false};
var myArray = [];
function RemoveFalseAndTransformToArray () {
for (var key in myObj) {
if(myObj[key] === false) {
delete myObj[key];
} else {
myArray.push(key);
}
}
}
RemoveFalseAndTransformToArray();
console.log("myObj: ", myObj);
console.log("myArray: ", myArray);
// result = ["105", "108"]
Please, let me know if you have any question.
To remove those properties you can use this algorithm:
for (k in myObj)
{
if (myObj.hasOwnProperty(k) && myObj[k] === false)
{
delete myObj[k];
}
}
If you are just interested in the keys of non-false values, you can use:
var keys = Object.keys(myObj).filter(function (k) {
return myObj[k] !== false;
});
The hasOwnProperty() check is necessary because objects may contain non-user properties (such as prototype) which you really don't want to mess with.
You need to iterate over the object using for...in loop
var myObj={105:true,183:false,108:true,106:false}
for(var key in myObj){
if(myObj.hasOwnProperty(key) && myObj[key] == false){
delete myObj[key];
}
}
console.log(JSON.stringify(myObj)) //{"105":true,"108":true}
console.log(Object.keys(myObj)) //["105", "108"]
ES6 has a one line way to do this, this mutates the original array!
Object.keys(myObj).map(key => !myObj[key] && delete myObj[key])
to avoid this use the spread operator
const filteredObj = [...myObj]
Object.keys(filteredObj).map(key => !filteredObj[key] && delete filteredObj[key])

How to determine if object is in array [duplicate]

This question already has answers here:
How do I check if an array includes a value in JavaScript?
(60 answers)
Closed 29 days ago.
I need to determine if an object already exists in an array in javascript.
eg (dummycode):
var carBrands = [];
var car1 = {name:'ford'};
var car2 = {name:'lexus'};
var car3 = {name:'maserati'};
var car4 = {name:'ford'};
carBrands.push(car1);
carBrands.push(car2);
carBrands.push(car3);
carBrands.push(car4);
now the "carBrands" array contains all instances.
I'm now looking a fast solution to check if an instance of car1, car2, car3 or car4 is already in the carBrands array.
eg:
var contains = carBrands.Contains(car1); //<--- returns bool.
car1 and car4 contain the same data but are different instances they should be tested as not equal.
Do I have add something like a hash to the objects on creation? Or is there a faster way to do this in Javascript.
I am looking for the fastest solution here, if dirty, so it has to be ;) In my app it has to deal with around 10000 instances.
no jquery
Use something like this:
function containsObject(obj, list) {
var i;
for (i = 0; i < list.length; i++) {
if (list[i] === obj) {
return true;
}
}
return false;
}
In this case, containsObject(car4, carBrands) is true. Remove the carBrands.push(car4); call and it will return false instead. If you later expand to using objects to store these other car objects instead of using arrays, you could use something like this instead:
function containsObject(obj, list) {
var x;
for (x in list) {
if (list.hasOwnProperty(x) && list[x] === obj) {
return true;
}
}
return false;
}
This approach will work for arrays too, but when used on arrays it will be a tad slower than the first option.
Why don't you use the indexOf method of javascript arrays?
Check this out: MDN indexOf Arrays
Simply do:
carBrands.indexOf(car1);
It will return you the index (position in the array) of car1. It will return -1 if car1 was not found in the array.
http://jsfiddle.net/Fraximus/r154cd9o
Edit: Note that in the question, the requirements are to check for the same object referenced in the array, and NOT a new object. Even if the new object is identical in content to the object in the array, it is still a different object.
As mentioned in the comments, objects are passed by reference in JS and the same object can exist multiple times in multiple structures.
If you want to create a new object and check if the array contains objects identical to your new one, this answer won't work (Julien's fiddle below), if you want to check for that same object's existence in the array, then this answer will work. Check out the fiddles here and in the comments.
Having been recently bitten by the FP bug reading many wonderful accounts of how neatly the functional paradigm fits with Javascript
I replicate the code for completeness sake and suggest two ways this can be done functionally.
var carBrands = [];
var car1 = {name:'ford'};
var car2 = {name:'lexus'};
var car3 = {name:'maserati'};
var car4 = {name:'ford'};
var car5 = {name:'toyota'};
carBrands.push(car1);
carBrands.push(car2);
carBrands.push(car3);
carBrands.push(car4);
// ES6 approach which uses the includes method (Chrome47+, Firefox43+)
carBrands.includes(car1) // -> true
carBrands.includes(car5) // -> false
If you need to support older browsers use the polyfill, it seems IE9+ and Edge do NOT support it. Located in polyfill section of MSDN page
Alternatively I would like to propose an updated answer to cdhowie
// ES2015 syntax
function containsObject(obj, list) {
return list.some(function(elem) {
return elem === obj
})
}
// or ES6+ syntax with cool fat arrows
function containsObject(obj, list) {
return list.some(elem => elem === obj)
}
try Array.prototype.some()
MDN Array.prototype.some
function isBiggerThan10(element, index, array) {
return element > 10;
}
[2, 5, 8, 1, 4].some(isBiggerThan10); // false
[12, 5, 8, 1, 4].some(isBiggerThan10); // true
You could use jQuery's grep method:
$.grep(carBrands, function(obj) { return obj.name == "ford"; });
But as you specify no jQuery, you could just make a derivative of the function. From the source code:
function grepArray( elems, callback, inv ) {
var ret = [];
// Go through the array, only saving the items
// that pass the validator function
for ( var i = 0, length = elems.length; i < length; i++ ) {
if ( !inv !== !callback( elems[ i ], i ) ) {
ret.push( elems[ i ] );
}
}
return ret;
}
grepArray(carBrands, function(obj) { return obj.name == "ford"; });
I used underscore javascript library to tweak this issue.
function containsObject(obj, list) {
var res = _.find(list, function(val){ return _.isEqual(obj, val)});
return (_.isObject(res))? true:false;
}
please refer to underscore.js documentation for the underscore functions used in the above example.
note: This is not a pure javascript solution. Shared for educational purposes.
You can just use the equality operator: ==. Objects are checked by reference by default, so you don't even need to use the === operator.
try this, just make sure you're using the correct variable reference in the place of car1:
var i, car, l = cars.length;
for (i = 0; i < l; i++)
{
if ((car = cars[i]) == car1)
{
break;
}
else car = null;
}
Edit to add:
An array extension was mentioned, so here's the code for it:
Array.prototype.contains = Array.prototype.contains || function(obj)
{
var i, l = this.length;
for (i = 0; i < l; i++)
{
if (this[i] == obj) return true;
}
return false;
};
Note that I'm caching the length value, as the Array's length property is actually an accessor, which is marginally slower than an internal variable.
I would use a generic iterator of property/value over the array. No jQuery required.
arr = [{prop1: 'val1', prop2: 'val2'}, {prop1: 'val3', prop2: 'val4'}];
objectPropInArray(arr, 'prop1', 'val3'); // <-- returns true
function objectPropInArray(list, prop, val) {
if (list.length > 0 ) {
for (i in list) {
if (list[i][prop] === val) {
return true;
}
}
}
return false;
}
You could try sorting the array based on a property, like so:
carBrands = carBrands.sort(function(x,y){
return (x == y) ? 0 : (x > y) ? 1 : -1;
});
Then you can use an iterative routine to check whether
carBrands[Math.floor(carBrands.length/2)]
// change carBrands.length to a var that keeps
// getting divided by 2 until result is the target
// or no valid target exists
is greater or lesser than the target, and so on, which will let you go through the array quickly to find whether the object exists or not.
try this ,
You can use the JavaScript some() method to find out if a JavaScript array contains an object.
<script>
// An array of objects
var persons = [{name: "Harry"}, {name: "Alice"}, {name: "Peter"}];
// Find if the array contains an object by comparing the property value
if(persons.some(person => person.name === "Peter")){
alert("Object found inside the array.");
} else{
alert("Object not found.");
}
</script>
EDIT 05/18/2022
The most simple way using ES6:
const arrayContainsObject = <T extends Record<string, unknown>>(array: T[], object: T) => {
return array.some(item => Object.keys(item).every(key => item[key] === object[key]))
}
Use like so:
const arr = [{
prop1: 'value1',
prop2: 'value2'
}]
const obj1 = {
prop1: 'value1',
prop2: 'value2'
}
const obj2 = {
prop2: 'value2',
prop1: 'value1'
}
const obj3 = {
prop0: 'value0',
prop1: 'value1'
}
arrayContainsObject(arr, obj1) // true
arrayContainsObject(arr, obj2) // true, even when props are arranged in different order
arrayContainsObject(arr, obj3) // false
Previous answer, don't use (because the order of props in an object needs to be identical)
const arr = [{
prop: 'value'
}]
const obj = {
prop: 'value'
}
arr.some((e) => Object.entries(e).toString() === Object.entries(obj).toString()) // true
i know this is an old post, but i wanted to provide a JQuery plugin version and my code.
// Find the first occurrence of object in list, Similar to $.grep, but stops searching
function findFirst(a,b){
var i; for (i = 0; i < a.length; ++i) { if (b(a[i], i)) return a[i]; } return undefined;
}
usage:
var product = $.findFirst(arrProducts, function(p) { return p.id == 10 });
This function is to check for a unique field.
Arg 1: the array with selected data
Arg 2: key to check
Arg 3: value that must be "validated"
function objectUnique( array, field, value )
{
var unique = true;
array.forEach(function ( entry )
{
if ( entry[field] == value )
{
unique = false;
}
});
return unique;
}
you can use Array.find().
in your case is going to look like this
carBrands.find(function(car){
let result = car.name === 'ford'
if (result == null){
return false;
} else {
return true
}
});
if car is not null it will return the javaScript Object which contains the string 'ford'
The issue with many of the answers here is that they will NOT find an object in an array that is equal to another object. They will only search for an EXISTING object that has a pointer to it in an array.
Quick fix using lodash to see if ANY equal object is in an array:
import _ from 'lodash';
_.find(carBrands, car1); //returns object if true, undefined if false
Working Plunker using this method: https://plnkr.co/edit/y2YX9o7zkQa2r7lJ
if its possible to use es6
carBrands.filter(carBrand => carBrand.name === carX.name).length > 0
if it's true there is a similarity
You can convert both the JSON objects to string and simply check if the bigger json contains the smaller json.
console.log(JSON.stringify(carBrands).includes(JSON.stringify(car1))); // true
console.log(JSON.stringify(carBrands).includes(JSON.stringify(car5))); // false
You could also a the findIndex
var carBrands = [];
var car1 = {name:'ford'};
var car2 = {name:'lexus'};
carBrands.push(car1);
if (carBrands.findIndex(f => f.name === car1.name) === -1) {
console.log('not contain')
} else {
console.log('contain')
}
if (carBrands.findIndex(f => f.name === car2.name) === -1) {
console.log('not contain')
} else {
console.log('contain')
}

Categories

Resources