I have this array:
var someArr = [1,2,3,4,5];
At some point I need to check that array is not null or length of the array > 0.
What is elegant way to implement it in Angularjs?
You can just check if the variable (array,object anything) has a truthy value or not. That means :
if( value ) {
}
will evaluate to true if value is not:
1. null
2. undefined
3. NaN
4. empty string ("")
5. 0
6. false
This is for above six conditions. But in case you have array define as:
var arr = [];
then you need to check arr.length
This question is more related to JavaScript, not AngularJS.
function nonEmpty(arr) {
return !!arr && arr.length > 0;
}
Examples:
nonEmpty(['a']) // true
nonEmpty([]) // false
nonEmpty(null) // false
nonEmpty(undefined) // false
I guessing you mean something like the following:
angular.isDefined()
Which is archievable by defining it yourself at the root of your application
angular.isNotNullOrZero = function(array) {
return !!array && !!array.length;
}
So you can use it throughout your application.
var someArr = [1,2,3,4,5];
console.log(angular.isNotNullOrZero(someArr);
etc..
But like others said, this is just plain JS.
Related
This question already has answers here:
Javascript: Using `.includes` to find if an array of objects contains a specific object
(7 answers)
Closed 23 days ago.
I'm attempting to find an object in an array using Array.prototype.includes. Is this possible? I realize there is a difference between shallow and deep comparison. Is that the reason the below code returns false? I could not find a relevant answer for Array.includes().
Array.includes compares by object identity just like obj === obj2, so sadly this doesn't work unless the two items are references to the same object. You can often use Array.prototype.some() instead which takes a function:
const arr = [{a: 'b'}]
console.log(arr.some(item => item.a === 'b'))
But of course you then need to write a small function that defines what you mean by equality.
Its' because both of the objects are not the same. Both are stored at different place in memory and the equality operation results false.
But if you search for the same object, then it will return true.
Also, have a look at the below code, where you can understand that two identical objects also results false with the === operator.
For two objects to return true in ===, they should be pointing to same memory location.
This is because the includes checks to see if the object is in the array, which it in fact is not:
> {a: 'b'} === {a: 'b'}
false
This is because the test for equality is not testing if the objects are the same, but whether the point to the same object. Which they don't.
You are on the right track but, the issue is the difference between reference and value types, you currently are using a reference type (object literal), so when you compare what is in the array with what you have, it will compare the references and not the values. this is what I mean:
var ar = [];
var x = {a: "b", c: "d" };
ar.push(x);
// this will log true because its the same reference
console.log("should be true: ", ar[0] === x);
ar.push({a: "b", c: "d" });
// this will log false because i have created
// a different reference for a new object.
console.log("should be false: ", ar[1] === x);
// Think of it like this
var obja = { foo: "bar" }; // new reference to 'obja'
var objb = { foo: "bar" }; // new reference to 'objb'
var valuea = 23;
var valueb = 23;
// 'obja' and 'obja' are different references
// although they contain same property & value
// so a test for equality will return false
console.log("should be false: ", obja === objb);
// on the other hand 'valuea' and 'valueb' are
// both value types, so an equality test will be true
console.log("should be true: ", valuea === valueb);
to achieve what you want, you either have to have added the actual reference, as I did above, or loop through the array and compare by unique property of the objects.
you can use find to returns the value of the this element
const array = [{a: 'b'}];
array.includes(array.find(el=>el.a==='b'));
const arr = [{a: 'b',b:'c'},{a: 'c'}]
console.log(arr.some(item => item.b === 'c'))
Yes, you can, if only so
const arr = [{a:'a'},{a: 'b'}]
const serch = arr[1]
console.log(arr.includes(serch))
You cannot use string comparisons on objects unless you first convert them to strings with...
JSON.stringify(TheObject)
So to loop through all objects in an array so as to prevent adding a duplicate object, you can use something like this...
let Bad=false;
ObjectArray.forEach(function(e){if(JSON.stringify(NewObject)===JSON.stringify(e)){Bad=true;}});
if(Bad){alert('This object already exists!');} else {ObjectArray.push(NewObject);}
I have to create a 2D Array of Optional Bool type and compare the value inside it but I can't.
The first time I try to declare in this way:
var Answ = [[Bool?]] ()
var Page = 0
for i in 0...4
{
if Answ[Page][i] == true
{...}
else if Answ[Page][I] == false
{...}
else
{...}
}
...
but when I launch the program, it says:
index out of range
when Xcode compares the Answ[Page][i] with the value true.
So, I try to modify the code and declare the array in this way:
var Answ = Array (repeating: Array (repeating: Bool?.self , count: 5), count: 40)
var Page = 0
for i in 0...4
{
if Answ[Page][i] == true
{...}
else if Answ[Page][I] == false
{...}
else
{...}
}
...
but at the same point, (if Answ[Page][i] == true) throws this error:
Binary operator '==' cannot be applied to operands of type 'Bool?.Type' (aka 'optional.Type') and 'Bool'"
Moreover, in other points of the code where I try to set a value of the array as true/false (Answ[Page][2] = true), Xcode says this:
cannot assign value of type 'Bool' to type 'Bool?.Type' (Aka'Optional.Type')
Can someone help me, please? Thank you in advance.
I found this topic:
Checking the value of an Optional Bool
but it didn't help me much.
You can compare optional bools as in the Q&A that you linked to. The problem is that
var Answ = Array (repeating: Array (repeating: Bool?.self , count: 5), count: 40)
creates a (nested) array of Bool?.self, which is the type of an optional bool, not a value of that type.
What you want is a (nested) array of Bool? values, initialized to nil:
var answers: [[Bool?]] = Array(repeating: Array(repeating: nil , count: 5), count: 40)
or alternatively:
var answers = Array(repeating: Array(repeating: Bool?.none , count: 5), count: 40)
You should provide a fallback value with ??.
By the way, you don't need to write == false or == true, it's redundant.
if Answ[Page][i] ?? false {
[...]
}
There are several issues with your code. First of all, don't use manual indexing in a for loop, rather use for ... in to have the indexes automatically handled for you. Secondly, a better solution for handling optional booleans is to safely unwrap the value using optional binding and then check the non-optional value. You also don't need to write if bool == true, if bool has the same meaning.
Also please make sure you conform to the Swift naming convention, which is lower-camelCase for variable names.
var answ = [[Bool?]] ()
var page = 0
for ans in answ[page]{
if let unwrappedAns = ans {
if unwrappedAns {
// answ[page][i] = true
} else {
}
} else {
//answ[page][i] = ans is nil
}
}
If you actually want to iterate through the whole array of arrays, this is one safe way for doing so:
for page in answ {
for ans in page {
//here ans = Answ[Page][i] when compared to the code in your question
if let unwrappedAns = ans {
if unwrappedAns {
} else {
}
} else {
//ans is nil
}
}
}
I'm trying to evaluate if an entered string partially matches any item in an array. When I use the following method in playgrounds it seems to work properly. However, when I use the exact same method in Xcode 9.0 beta 6 (9M214v) it doesn't return the correct answer.
func isValid(_ item: String) -> Bool {
let whitelist = ["https://apple.com","https://facebook.com","https://stackoverflow.com"]
return whitelist.contains(where: {$0 <= item ? true : false })
}
There's also anomalies like when I passed in "https://twitter.com" it'll return true. Am I nuts? And while I'm here, anyone have a different approach to solve this problem?
theres also anomalies like when I passed in "https://twitter.com"
it'll return true.
Whether the version of Swift is 3 or 4, based on your code snippet you should get the same true result! Why?
because the logic of contains(where:) of doing the comparison is related to the logic of the equality of the given elements, i,e you cannot use contains with array of non-equatable elements. To make it more clear:
"https://apple.com" <= "https://twitter.com"
"https://facebook.com" <= "https://twitter.com"
"https://stackoverflow.com" <= "https://twitter.com"
the result would be true for all statements ('t' character is greater than 'a', 'f' and 's').
Thus:
"https://zwebsite" <= "https://twitter.com"
would returns false ('t' is less than 'z').
However, to get the expected result, you could implement your function like this:
func isValid(_ item: String) -> Bool {
let whitelist = ["https://apple.com","https://facebook.com","https://stackoverflow.com"]
return whitelist.contains { $0 == item }
}
Or for even a shorter contains:
return whitelist.contains(item)
Which leads to let
isValid("https://twitter.com")
to returns false.
Just return the following, which will return true or false:
return whitelist.contains(item)
self.scope.savesectioneditmain = [self.scope.savesection2details,
self.scope.editsection2,
self.scope.savesection1details,
self.scope.editsection1];
Based on above codes, I want to check all array value equal to true value.
if($.inArray(true, self.scope.savesectioneditmain) == 0)
I have tried $inArray, but $inArray checks only one condition, but I want to check all array value should be equal to true.
You can use Array.prototype.every()
The every() method tests whether all elements in the array pass the test implemented by the provided function.
if(self.scope.savesectioneditmain.every(x => x == true)){
//All elements are true
}
I can't understand why it's always shows NOT equal in code :
if(JSON.stringify(data.content.items) != JSON.stringify(updatedItems)) {
console.log('update');
updatedItems = data.content.items; // updatedItems -global variable
}
I receive array of objects and check every second if it's equal or not.
Use angular.fromJson(json) instead. It will strip the $$hashKey, that's making it not equal