How can I check if javascript array already contains a specific array - javascript

I learn Javascript and read and understand how the includes works to test if a value exists in an array.
My problem comes when I have an Array of items that look like this this:
state = { focused: null, files: [] };:
The image show this here:
When I add a new newFile and it's the same it should not add it ok but the evaluation,
if (newFile && !files.includes(newFile)) {.. always say false so how to test for this do I have to test on individual values inside newFiles?

Array.includes will not do a deep comparison between object, only a shallow one comparing references. This way even objects that have same values they would fail on test because they have different references.
In your case you could compare id, which should be unique for each object. You can use Array.every that checks if all values pass in the test. This way you want to check that every file id doesn't match newFile id:
if (newFile && files.every(({id}) => newFile.id !== id))

Array.includes does reference comparison for Array or Object, so instead you can use Array.filter
if (newFile && newFile.filter(e => { /*Comparison logic */ }).length > 0)

Related

Jquery isEmptyObject returns true even though it is not

This is the jquery code i am using
console.log(arrayPgggoData[taxonomy]);
console.log(jQuery.isEmptyObject(arrayPgggoData[taxonomy]));
And I don't know why it is returning true.
Also, what I am actually trying to see if the key inside is not an empty string.
The documentation clearly states:
The argument should always be a plain JavaScript Object as other types of object (DOM elements, primitive strings/numbers, host objects) may not give consistent results across browsers. To determine if an object is a plain JavaScript object, use $.isPlainObject()
But you are checking over an array.
To check if an array has no elements, you can simply rely on its .length property.
arrayPgggoData[taxonomy].length === 0
If you have some array values that you want to consider as "empty" values, then .filter method is your friend.
nonEmptyValues = arrayPgggoData[taxonomy].filter(function(el) { return el !== '' })
ES6 friendly syntax
const nonEmptyValues = arrayPgggoData[taxonomy].filter(el => el !== '')

How to check if object is empty using lodash _isEmpty?

i have map function that is returning empty object for the array now if i check array _isEmpty this condition should satisfy but its not getting into if statement. Any idea what is implemented wrong or better approach ?
main.js
const validateResponse = _.map(drugs ,validateValues);
now validateResponse returns [{}] and it should satisfy condition
if (_.isEmpty(validateResponse)) {
throw invalidPriceError;
}
As per the lodash documentation here:
Array-like values such as arguments objects, arrays, buffers, strings, or jQuery-like collections are considered empty if they have a length of 0. Similarly, maps and sets are considered empty if they have a size of 0.
[{}].length happens to be 1. A cabbage-in-a-box, if you will. An array with one empty object. Hence, isEmpty evaluates to false. [].length, on the other hand, equals 0.
You'll have to compact out the internals or check one level deeper:
if (!validateResponse.filter(r => !_.isEmpty(r)).length){
throw invalidPriceError;
}
There might be a handful of other cases you want to cover, like empty array, or an array of two empty objects, etc. Variations on the following should do what you need...
let array = [{}];
// contains any empty object
console.log(_.some(array, _.isEmpty))
// contains only empty objects
console.log(_.every(array, _.isEmpty))
// contains exactly one empty object
console.log(_.every(array, _.isEmpty) && array.length == 1)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.core.js"></script>
If you just want to check if there is a single array with a single empty object [{}] you can use _.isEqual:
const hasEmpty = arr => _.isEqual(arr, [{}])
console.log(hasEmpty([])) // false
console.log(hasEmpty([{}])) // true
console.log(hasEmpty([{}, {}])) // false
console.log(hasEmpty([{ a: 1 }])) // false
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Since the array isn't actually empty, but what you're truly checking for is "does the array have exactly one value, and is that single value an empty object?", you could just do this check:
if (validateResponse.length === 1 && _.isEmpty(validateResponse[0])) {
throw invalidPriceError;
}

Right-hand side of instanceof is not callable

So, i'm trying to make a simple Discord Bot using javascript, and I want to detect if a player username is on the banned list.
I have an array
var banned = ['Andrew','David']
and an if
if (message.author.username instanceof banned) {.....
but when I run it, it outputs
if (message.author.username instanceof banned)
^
TypeError: Right-hand side of 'instanceof' is not callable
What can I do?
This is not what instanceof is for. instanceof is used to see if an object is an instance of a specific constructor (ex: banned instanceof Array).
If you just want to see if an element is in an array, you can use .indexOf().
if(banned.indexOf(message.author.username) != -1)
I was getting the same error on vue / nuxt js.
The problem was setting the prop type wrong:
blog: {
type: {},
required: false,
},
The right way doing it is setting the type Object instead {}
blog: {
type: Object,
required: false,
},
instanceof is used to check if an object is an instance of a class. What you want to do is to check if a string is in an array like this:
if (banned.indexOf(message.author.username) >= 0) {...
instanceof is used to see if an object is of a particular type. You're trying to see if an object is a member of an array.
Try the includes or indexOf methods of the Array object.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
I know I am late here to answer, but I would definitely consider includes() when it comes to code maintainability and first impression of the code.
ES2016 Specifications included the includes() for Array data structure. The includes() check whether an array includes a certain element, returning true or false as appropriate.
But in ES5 we are used to performing operations like this with indexOf() method.
Why use includes?
The includes method finds NaN and undefined whereas the indexOf method doesn't.
Example to find NAN in the array:
const array = [NaN];
if (array.indexOf(NaN) == -1){
console.log("NaN not found in the array");//NaN not found in the array
}
const array1 = [NaN];
if (array1.includes(NaN)){
console.log("true. NAN was found in the array");// true. NAN was found in the array
}
Example to find undefined in the array:
const array = [, , , ,];
if(array.includes(undefined)){
console.log("true array elements are undefined");// true array elements are undefined
}
const array1 = [, , , ,];
if(!array1.indexOf(undefined) == -1 ){
console.log("true. array elements are undefined");
}else {
console.log("Sorry can't find undefined");// Sorry can't find undefined
}
The includes method does not distinguish between -0 and +0(This is not a bug, but clearly how javascript works.
const a = [-0].includes(+0);
console.log(a);//true
In many cases, I have seen indexOf is little faster than include. It depends where you need to compromise. Also, ES6 includes performance is very fast as compared to lodash's includes method.
Performance comparison source.

Why pushing a values into my array is beeing skipped?

I am developing a React Native App. In my Code i am fetching data from server. This data is used in my ListView which parameter is dataSource. This code works actually. Now i wanted to fill the array with data, only when the values doesn´t exists yet.
So: Push Value to Array, if index is bigger than -1:
if (friendsArray.indexOf(x.id) > -1) {
friendsArray.push(x);
self.setState({
dataSource: self.state.dataSource.cloneWithRows(friendsArray)
});
}
In my debugger i see that, the Line:
friendsArray.push(x);
Will be skipped everytime... Any ideas?
I believe you have two errors here.
First, if you want to execute the push when an item is not in the array, you'll want to do friendsArray.indexOf(x.id) == -1. Checking for > -1 is checking that the item already exists in the array.
Second, you're checking if x.id is in the array, but then pushing x. You probably mean to either be checking if x is in the array, or pushing x.id? If the former (you want to check if x is in the array), you'll need a different solution as objects in javascript will always fail an equality comparison. You would instead probably want to do something like check if any of the objects in friendsArray have an id that matches the id of the object you're trying to push. That could be accomplished with something like this:
if (friendsArray.filter(function(a) { return a.id == x.id; }).length == 0) {
// friendsArray does not contain an object with that id
}

Underscore uniq not working in Parse

I've got a simple array cars of Parse models of class Cars
When I do
var uniqCars = _.uniq(cars);
it doesn't work. uniqCars is exact same as cars. The length of cars is 5 and length of uniqCars is 5 (when it should be 2).
However, when I do:
var uniqCars = _.uniq(cars,
function (c) {
return c.id;
});
It works. My question is, why doesn't it work with the former and works with the latter? Why do I have to be so verbose? Is this an issue with Parse or underscore?
why doesn't it work with the former
because, if you don't pass the comparator function, it by default uses === operator to compare the objects. Quoting the _.uniq documentation,
Produces a duplicate-free version of the array, using === to test object equality. ... If you want to compute unique items based on a transformation, pass an iteratee function
When you use === (Strict Equality operator), no two objects will be the same unless they are one and the same object or same sequence of characters forming a string. For example,
console.assert(({} === {}) === false);
var obj = {};
console.assert(obj === obj);
console.assert("ab" === "a" + "b")
console.assert("ab" === 'a' + "b")
So, it is not specific to Parse but it is the expected behaviour in JavaScript.
The comparisons are made using strict equality. Unless there are multiple references to the same object in the array, they are not going to be strictly equal.
Produces a duplicate-free version of the array, using === to test object equality. In particular only the first occurence of each value is kept. If you know in advance that the array is sorted, passing true for isSorted will run a much faster algorithm. If you want to compute unique items based on a transformation, pass an iteratee function.

Categories