localhost
localhost

Reputation: 871

Getting second last occurrence and capturing the string after that

I have the following url string as a example

https://jsonplaceholder.typicode.com/todos/101/'

I want to store 101 so I can use that part of string in some other logic. I tried the following.

const filter = (value)=>{
    return value.split("/").pop();
})

but it returns empty, from what I know, as pop(), pop off last but and last bit is only / and nothing after that.

How can I modify my code to give me the value after the second to last /

Upvotes: 1

Views: 1371

Answers (5)

MiB
MiB

Reputation: 621

An alternative could be a regex pattern, but this is as brittle as any solution that assumes URL structures will never change. Relying on URLs for the id is probably not the most solid approach. Surely the JSON stream holds the actual ids somewhere, at least indirectly in the linked objects?

Explanation of the matching pattern /\/(\d+)\/?$/ used in the example below:

  1. \/ matches a forward slash, escaped with a backslash.
  2. (\d+) gets one + more digits
  3. \/? gets optional /, escaping it.
  4. $ matches end of string
  5. The first and last / are JS regex delimiters, so aren't functional parts of the matching pattern.

Most of this is touched upon in the Regular expressions at MDN. Also see String.prototype.match() for this method.

const url = 'https://jsonplaceholder.typicode.com/todos/101/';
const idInUrlPattern = /\/(\d+)\/?$/;
//? handles a null case, [1] returns the matching group
const getIdFromUrl = url => url.match(idInUrlPattern)?.[1];
console.log(getIdFromUrl(url));

Upvotes: 0

cinch
cinch

Reputation: 192

You can extract the number before the last '/' as follows.

const url = 'https://jsonplaceholder.typicode.com/todos/101/';

const filter = value => {
    let segments = value.split('/');
    return segments[ segments.length -2];
}

console.log(filter(url));

Upvotes: 0

Kobe
Kobe

Reputation: 6457

If you're not sure if there will be a trailing slash, you can use filter to remove all empty elements, and then pop the '101':

const filter = value => value.split('/').filter(i => i).pop()

console.log(filter('https://jsonplaceholder.typicode.com/todos/101/'))
console.log(filter('https://jsonplaceholder.typicode.com/todos/101'))

filter(i => i) simply loops over each item in the array to see if it evaluates to true, so all falsy items like '' or undefined will be removed.

Upvotes: 3

SlimeyBadger102
SlimeyBadger102

Reputation: 34

When you split, the last / gets split as an empty string, which you receive when you pop(). If we remove it before splitting you will get the result you want.

You could do this oneliner value.slice(0, -1).split('/').pop();

Upvotes: 1

CertainPerformance
CertainPerformance

Reputation: 371233

Because the URL ends in the delimiter you're splitting on, the last item in the resulting array will be the empty string, and the second-to-last item will be the match you're looking for. You can .pop() twice:

const filter = (value)=>{
  const splits = value.split('/');
  splits.pop();
  return splits.pop();
};

Or you could use a regular expression to match non-/ characters, followed by / and the end of the string::

const filter = value => value.match(/[^\/]+(?=\/$)/)[0];
console.log(filter('https://jsonplaceholder.typicode.com/todos/101/'))

Upvotes: 1

Related Questions