Reputation: 253
I have some code like these:
let url = "/user_auth/devices";
const params = ["clientId = 909090", "name = peter", "active = true"];
for (let i=0; i < params.length; i++) {
url += i > 0 ? "&" + params[i] : "?" + params[i];
}
The output will be something like: "/user_auth/devices?clientId = 909090&name = peter&active = true"
;
What I don't understand is that inside the for loop, since url
is a string, how does a string plus a number being greater than 0?
I've tested with it:
when url
plus 0, the output is /user_auth/devices0
and turns to be false
when compare with 0.
when /user_auth/devices0
plus 1 the output is /user_auth/devices01
and the result is also false when compare with 0.
Does anyone know why a string plus 0 could be greater than 0?
Upvotes: 0
Views: 92
Reputation: 2957
The snippet url += i > 0
is not performing a comparison between the url
(a string) and 0
(a number), rather it does a comparison between i
(the loop counter) and the constant 0
; and both are numbers.
In order to understand what is happening, you first have to understand two things:
?:
+=
I will address the shortcut assignment operator first. Then I will explain the ternary operator.
+=
The shortcut assignment operator lets you increment and assign a value in one step. Rather than doing something like this:
a = a + 5; // first increment a by 5, then assign the result to a
This operator lets you do something like this:
a += 5; // increment and assign the result of increment a by 5 in one step
?:
The ternary operator is a shortcut way to perform an if...else
operation. It is called a ternary operator because it accepts three (3) operands. For example, the classical if...else
statement is written like this:
if(condition) {
// code to execute if condition is true
} else {
// code to execute otherwise
}
The ternary operator lets you do the above in a more elegant and concise way:
condition ? code_to_execute_if_condition_is_true : code_to_execute_otherwise
In the above snippet, the operator is the ?:
, and the operands are as follows:
condition
code_to_execute_if_condition_is_true
code_to_execute_otherwise
The operation can also be broken into two parts:
The first part is the part from the condition
up until the :
, and is similar to the if(condition)
of a classical if...else
. If that condition is true, the code between the ?
and the :
will be executed. It is just as if you wrote:
if(condition) {
// code_to_execute_if_condition_is_true
}
The second part is the part following the :
, and the code following it is executed if the condition is false. It is as if you wrote:
else {
// code_to_execute_otherwise
}
Important: But please note that the ternary operator is one: ?:
you cannot use either part in isolation. They must always be used as specified above.
Now, coming to the issue at hand, this is your code:
let url = "/user_auth/devices";
const params = ["clientId = 909090", "name = peter", "active = true"];
for (let i=0; i < params.length; i++) {
url += i > 0 ? "&" + params[i] : "?" + params[i];
}
I will first explain the part inside the loop:
url += i > 0 ? "&" + params[i] : "?" + params[i];
This code snippet can be split into two parts:
url +=
Based on what we have explained so far, this is a shortcut way of writing:
url = url + // something (we will get to that something in a bit)
i > 0 ? "&" + params[i] : "?" + params[i];
This is the ternary operator at play here, and it is like writing:
if(i > 0) {
return "&" + params[i];
} else {
return "?" + params[i];
}
Earlier, we talked about url +=
as being equivalent to url = url + // something
. That something
is what is returned from the second part:
i > 0 ? "&" + params[i] : "?" + params[i];
.
And whatever that is is tacked onto the end of the url.
So that if i
is greater than 0
(which is the case in all but the first iteration), the url
will be
url = url + "&" + params[i]
.
However, if i
is 0
(which is the case on the first iteration), the url
will be
url = url + "?" + params[i]
.
Since your initial url
string is: "/user_auth/devices";
, substituting the different iteration values for params[i]
, we will have:
on the first iteration,
i === 0
params[i]
equals "clidenId = 909090"
So, we will have url = url + "?" + "clientId = 909090"
.
Resulting in: "/user_auth/devices?clientId = 909090";
On the second iteration,
i === 1
(and therefore greater than 0)
params[i]
equals "name = peter"
we will have url = url + "&" + "name = peter"
Resulting in: "/user_auth/devices?clientId = 909090&name = peter";
The same process is repeated on the third iteration (and any subsequent iteration if you add some other elements to the params
array). But since i
will be greater than 0
in all subsequent iterations, the result will be obtained via a similar process to the second iteration.
Upvotes: 1
Reputation:
the interpreter evaluates the code from right to left.
Thus in url += i > 0 ? "&" + params[i] : "?" + params[i];
it starts by evaluating the result of i > 0 ? "&" + params[i] : "?" + params[i]
, then, it concatenates the result in url +=...
as other has shown, this code can be written such as:
if (i > 0) {
url += "&";
} else {
url += "?";
}
url += params[i];
Upvotes: 1
Reputation: 177692
Any string is > 0 but you just have a poorly written ternary that tests if the loop is iteration 0 or higher
use the URLSeachParams, then no need to test the & or ?
const params = ["clientId = 909090", "name = peter", "active = true"];
const sp = new URLSearchParams()
params.forEach(parm => {
const [name,value] = parm.split("=");
sp.set(name.trim(),value.trim()); // trim could be avoided if you had a proper key/value object
})
console.log("/user_auth/devices?"+sp.toString())
Your unpleasant array can be processed with some simple replace too
const params = ["clientId = 909090", "name = peter", "active = true"];
const search = "?"+params.toString().replace(/\s+/g,"").replace(/,/g,"&")
console.log(search)
Upvotes: 0
Reputation: 22766
This url += i > 0 ? "&" + params[i] : "?" + params[i];
is just syntactic sugar (it is called the ternary operator, which is equivalent) to:
if (i > 0) {
url += "&" + params[i];
} else {
url += "?" + params[i];
}
i
is not being added to url
, and only i
is being compared to 0
. And it could also be reduced to this (by factoring out params[i]
):
url += (i > 0 ? "&" : "?") + params[i];
Upvotes: 2
Reputation: 789
This is a ternary expression:
i > 0 ? "&" + params[i] : "?" + params[i];
It will return "&" + params[i]
when i
is higher than 0
and "?" + params[i]
otherwise.
In your code, you are using the +=
operator which adds the value returned from your ternary expression to the url.
To summarize, you are not comparing a string
and a number
with 0
. You are adding the result from a ternary operation to a string
(your variable url
).
Upvotes: 2