problem with an if statement - objective-c

For some reason the argument I pass to my if statement is not true for even though it should be heres my code:
if (currentAttribute == cBusName)
{
NSLog(#"currentAttribute == cBusName");
}
current attribute and cBusName are both NSMutableStrings an both equal "1" but the NSLog never outputs the string in the console is there something I am missing???

The == operator is comparing that those objects are the same object (IE they point to the same address in memory), not that their values are the same.
Try
if ([currentAttribute isEqualToString: cBusName])
{
NSLog(#"currentAttribute == cBusName");
}
which compares the values of the two strings, not their location in memory.

String objects cannot be compared
using the equality (==) operator. The
reason for this is that any attempt to
perform a comparison this way will
simply compare whether the two string
objects are located at the same memory
location. Let's take a look at this
via an example:via an example:
from http://www.techotopia.com/index.php/Working_with_String_Objects_in_Objective-C, search for Comparing Strings

Related

Firestore rules variable in path compare to data

I want to compare a variable in the path with a entry in my document. I build the following rule:
match /{userId}/test/{cycle}/results {
//allow read: if 3 == get(/databases/$(database)/documents/$(userId)/status).data.number
allow read: if cycle == get(/databases/$(database)/documents/$(userId)/status).data.number
}
The commented out line works perfectly which means that the {cycle} variable in my path works and the correct number is transferred but when I want to compare the cycle variable with the number out of the databse it doens't work.
Is it possible that I compare strings with numbers or anything like this???
Thanks!!
I could solve it myself. The problems was that I compared a string with a Number. The path delivered by the request as a string which also defines the {cycle} variable as a string. I compared it with my data from my database which was a number...
Solution, convert the number into a string
match /{userId}/test/{cycle}/results {
allow read: if cycle == string(get(/databases/$(database)/documents/$(userId)/status).data.number)
}
For more: https://firebase.google.com/docs/reference/rules/rules.String

What are the advantages of returning -1 instead of null in indexOf(...)?

When calling List.indexOf(...), what are the advantages of returning -1 rather than null if the value isn't present?
For example:
val list = listOf("a", "b", "c")
val index = list.indexOf("d")
print(index) // Prints -1
Wouldn't it be a cleaner result if index was null instead? If it had an optional return type, then it would be compatible with the elvis operator :? as well as doing things such as index?.let { ... }.
What are the advantages of returning -1 instead of null when there are no matches?
Just speculations but i could think of two reasons:
The first reason is to be compatible with Java and its List.indexOf
As the documentation states:
Returns:
the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the element
The second reason is to have the same datatype as kotlins binarySearch.
Return the index of the element, if it is contained in the list within the specified range; otherwise, the inverted insertion point (-insertion point - 1). The insertion point is defined as the index at which the element should be inserted, so that the list (or the specified subrange of list) still remains sorted.
Where the negative values actually hold additional information where to insert the element if absent. But since the normal indexOf method works on unsorted collections you can not infer the insertion position.
To add to the definitive answer of #Burdui, another reason of such behavior is that -1 return value can be expressed with the same primitive Int type as the other possible results of indexOf function.
If indexOf returned null, it would require making its return type nullable, Int?, and that would cause a primitive return value being boxed into an object. indexOf is often used in a tight loop, for example, when searching for all occurrences of a substring in a string, and having boxing on that hot path could make the cost of using indexOf prohibitive.
On the other hand, there definitely can be situations where performance does not so matter, and returning null from indexOf would make code more expressive. There's a request KT-8133 to introduce indexOfOrNull extension for such situations.
Meanwhile a workaround with calling .takeIf { it >= 0 } on the result of indexOf allows to achieve the same.

Objective-C: Exclamation Point strcmp in "if" statement

I am looking over some OpenGL ES code to multiplay matrices, but I'm not sure about how this if statement works:
for (int i = 0; i <_uniformArraySize; i++) {
**if (!strcmp(_uniformArray[i].Name, "ModelViewProjectionMatrix")) {**
GLKMatrix4 modelViewProjectionMatrix = GLKMatrix4Multiply(_projectionMatrix, _modelViewMatrix);
glUniformMatrix4fv(_uniformArray[i].Location, 1, GL_FALSE, modelViewProjectionMatrix.m);
}
}
Does !strcmp mean that the strings are equal or not equal? I looked at the strcmp documentation and it returns numbers. So how does this exclamation point in an if statement affect a number (being the return value of strcmp)?
Thanks
Since Objective C, like C, allows integers in conditionals, using !expr is a common shorthand for expr== 0.
Your statement is equivalent to
if (strcmp(_uniformArray[i].Name, "ModelViewProjectionMatrix") == 0) {
...
}
Since strcmp returns zero when strings are equal to each other, the condition checks if the content of two C strings is the same.
strcmp() function returns the total number of differences found between each string, so a zero means there are no differences. It is kind of un-intuitive when you think of it in terms of strcmp true/false.
The exclamation mark is the 'NOT' operator. This means that it will test whether the value in front of it is NOT true, so the result is essentially a reversal of the original boolean value.
In this case, if !strcmp() means if the result of strcmp is NOT > 0 then the result is true.
strcmp will return zero when strings are equal. The exclamation point is the negation operator so the program will enter the if statement when strings are equal.

Why don't two items at the same location in memory return true in an if statement

I'm trying to compare two files by fileId. fileId is an NSNumber.
I was surprised that while file and lFile had the same location in memory, the if statement did not return true, and did the method did not return true until my comparison using isEqualToNumber was true.
Why would two items with the same memory address not return true using == for the comparison?
Look carefully. Note that you aren't comparing the addresses of file and lfile, you're comparing the values returned by their respective fileId properties.
If the fileId property returns a copy of the underlying NSNumber object, then the two values returned will not compare equal with the equality (==) operator, because they are two distinct objects. They are, however, going to be considered equal by the isEqualToNumber: method.

Perform an assignment and an operation using a ternary operator + && in Objective-C?

In the name of ternary bliss (and for a disdain of the verbose)... I am hoping, and am somewhat surprised that....
BOOL isItOpen = YES;
isItOpen = (isItOpen ? YES : NO); // yes, dumbie, it's open.
works fine… but that…
isItOpen = (isItOpen ? [it close] && NO : [it open] && YES);
results in Invalid operands to binary expression ('void' and 'int')
I can't seem to track down a simple yes or no as to whether one can conditionally chain operations with && (or ||), like one does in say, BASH or PHP. I tried various combinations of & and && arrangements, to no avail.. as I am a C idiot... but if this "way of doing it" is NOT possible, linguistically… is there another - that is as concise? (ie, no ifs involed?)
The C (and by extension, C++ and Objective-C1) operators form expressions; they're designed to evaluate to a value, rather than control program flow.
So whilst ?:, && and || all offer short-circuit evaluation of their arguments, you can't use them to conditionally call arbitrary functions;2 you should use traditional control-flow constructs (i.e. if) for that.
You could use the little-known comma operator to achieve this, but I strongly recommend that you don't, because it's highly unidiomatic, and difficult to read. e.g.:
isItOpen = condition ? (func1(), NO) : (func2(), YES);
Actually, I don't know Objective-C. For all know, it might be possible!
And by "arbitrary", I mean functions that return void, or a type that's not implicitly convertible to bool in the case of && and ||, or a non-matching type in the case of ?:.
The difference you are experiencing is due to Objective-C having:
(a) true procedures (void functions/methods) which return no value; and
(b) a stronger type system than PHP
In your example the primary problem is (a) - you are calling methods which return nothing, and nothing is not a boolean value.
In PHP functions always return something, a function defined as returning void is actually defined as returning a "useless" value. However PHP will convert just about anything to anything (and does so inconsistently, for added "fun"), so a "useless" value has a boolean value - though what that is probably depends on the phase of the moon ;-) This feature does mean that you can reliably chain a "void" function after one which returns a value - <expr convertible to boolean> && <"void" function> will work in PHP (but the resulting boolean value is arbitrary). The same thing will not work in Objective-C (do not try to fix it with the comma operator, there are hidden traps with that operator).
So provided you stick with functions/methods which return either a boolean, or a type implicitly or explicitly convertible to boolean (e.g. for pointer types nil is false, other values true; for integral types 0 is false, everything else true) you can "conditionally chain" operations. Whether you should do this is a different question...
P.S. If you want to be confusing, this is short:
(isItOpen = !isItOpen) ? [it open] : [it close];
which will make most folks do a double-take ;-)
Your code would work fine as long as the close and open methods you are executing on it return boolean values. Otherwise, no cigar.
If you want to use the ternary operator, you can do like this:
isItOpen ? ([it close], isItOpen = NO) : ([it open], isItOpen = YES);
Or:
isItOpen ? [it close] : [it open];
isItOpen = !isItOpen;
But this is not a good programming style and you should avoid it.
The following code is much more readable (at least by a C/C++/Objective-C programmer):
if (isItOpen)
[it close];
else
[it open];
isItOpen = !isItOpen;
In order of preference, I recommend you use the third version of the code, then the second, then the first.