Reputation: 21282
var path = document.location.pathName;
example.com/store/order/cats
Sometimes it might be:
example.com/store/order/cats/
Note the slash at the end.
I'd like a function to return cats in either case. If there is no trailing slash I go:
function() {
return path.split('/').pop();
}
But if there is a trailing slash, I need to pop()
twice. I tried this:
function() {
return path.split('/').pop().pop();
}
Which threw an error.
So the array arising from split('/') can be either:
["", "store", "order", "cats", ""] // trailing slash
or
["", "store", "order", "cats"] // no trailing slash
How can I return cats in either eventuality?
Upvotes: 2
Views: 7241
Reputation: 4705
There are indeed many ways to skin a cat. These assume you want one liners rather than something more defensive and that performs well.
If you always want the second from last
[1,2,3,4,5].slice(-2).shift()
4
This will likely perform very slightly better:
[1,2,3,4,5].slice(-2, -1)[0]
4
To extract all non-empty delimited items:
'/a/b//c/d/'.match(/[^\/]+/g)
[a, b, c, d]
Upvotes: 2
Reputation: 7285
As you can see in this JSFiddle http://jsfiddle.net/zarjay/mbggs/ pop
is a lot more efficient than RegExp
Have a look at this bit of code now:
function( ) {
var paths = path.split( "/" ),
cats = paths.pop( );
if( !cats ) {
cats = paths.pop( );
}
return cats;
}
You see after you pop
paths the first time, you remove the last element of the array
Now if you find that that element is empty, you just pop
again and you get the element you want
Your performance is going to be a lot better and if you ever use this in a loop with thousands of iterations you'll get a performance boost in the order of seconds
And that's neat
Upvotes: 1
Reputation: 4053
Array.pop() returns the last element, not the original Array. So the second pop() is called on the last element. If it does not have pop method, you get an error...
To get the second path element from the end use path.replace(/.*\/([^\/]+)\/([^\/]+)\/?$/,'$1')
Upvotes: 1
Reputation: 2425
This is by far the simplest approach:
// Couldn't resist :)
function getCats( location ) {
if ( location.charAt( location.length-1 ) == "/" ) {
location = location.slice(0, -1)
}
return location.split("/").pop()
}
Upvotes: 1
Reputation: 3170
As others have said, you could try removing the last character if it is a slash, and then using the first method.
function getLastWordInPathName() {
var path = document.location.pathName.replace(/\/$/, '');
return path.split('/').pop();
}
However, your question was asking why you can't call pop()
twice.
The first time you call pop()
, the value of the last element in the array is returned. When you call pop()
again, this function is applied to the result of the previous function - so you are calling pop()
on the string '/'
, and not on your array.
Upvotes: 3
Reputation: 87203
You can first remove the last trailing /
from the string and then use pop
on the resulting string.
var path = document.location.pathName.replace(/\/$/, '');
var pathName = path.split('/').pop();
The regex \/$
will match the trailing /
from the string. The /
need to escape by preceding with \
.
You can also use string methods as follow:
if (path.charAt(path.length - 1) === '/') {
path = path.substr(0, path.length - 1);
}
Upvotes: 1
Reputation: 413826
You can just iterate and throw away empty path elements at the end:
function pathTail(path) {
for (var split = path.split("/"), tail = split.pop(); !tail; tail = split.pop());
return tail;
}
Or you can use a regular expression:
function pathTail(path) {
return path.replace(/^.*\/([^/]+)\/*$/, "$1");
}
Upvotes: 0