Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[11.x] Add splitLast string helper method #53505

Open
wants to merge 5 commits into
base: 11.x
Choose a base branch
from

Conversation

ash-jc-allen
Copy link
Contributor

@ash-jc-allen ash-jc-allen commented Nov 13, 2024

Hey! This PR proposes a new Str::splitLast helper method for use with strings. It splits a string into 2 pieces based on the last occurrence of a search value.

Apologies if something like this already exists and I've just not seen it haha!

I'm not sure if it's something that'd be useful to anyone else outside my current project, but I thought I'd propose it just in case.

Context

I've recently been working on a feature for a project where I need to split a full software name (e.g. Google Chrome 10) to get it's name and version number (e.g. "Google Chrome" and "10").

I was using something like this:

$fullSoftwareName = 'laravel framework 12';

$softwareName = Str::beforeLast($fullSoftwareName, ' '); // laravel framework
$softwareVersion = Str::afterLast($fullSoftwareName, ' '); // 12

I thought it'd be nice to use something like this that wraps it all up:

$fullSoftwareName = 'laravel framework 12';

[$softwareName, $softwareVersion] = Str::splitLast($fullSoftwareName, ' ');

// $softwareName: 'laravel framework'
// $softwareVersion: '12'

Examples

By default, the search value won't be included in the returned result:

[$before, $after] = Str::splitLast('taylor otwell', 'twe');

// $before: 'taylor o'
// $after: 'll'

Or, you can pass "before" to the includeSearch argument to append the search value to the first item:

[$before, $after] = Str::splitLast('taylor otwell', 'twe', includeSearch: 'before');

// $before: 'taylor otwe'
// $after: 'll'

Or, you can pass "after" to the includeSearch argument to prepend the search value to the second item:

[$before, $after] = Str::splitLast('taylor otwell', 'twe', includeSearch: 'after');

// $before: 'taylor o'
// $after: 'twell'

If the search value isn't found (or an empty string is passed as the search value), then the subject will be returned as the first value of the array:

[$before, $after] = Str::splitLast('taylor otwell', 'ash');

// $before: 'taylor otwell'
// $after: ''

As I say, I don't know if this is just a niche use case that won't be encountered that often, but I thought I'd propose it in case in could come in handy for anyone else.

If it's something you think might be worth merging, please let me know if there's anything you'd like me to change 😄

Copy link
Contributor

@morloderex morloderex left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First off great addition 👍

However i don't feel like passing before and after as strings for the $includeSearch parameter is totally clear if $includeSearch is just declared as a string parameter. Maybe we should split out the parameter and instead use 2 boolean parameters. Something like prependSearch and appendSearch.

Making the signature splitLast($subject, $search, $appendSearch = false, $prependSearch = false).

Then using named parameters it would become splitLast(subject: $subject, search: $search, appendSearch: false, prependSearch: true)

Alternatively we could add 2 additional helper methods for where the flags for $includeSearch are set correctly i just don't have anything good for naming these methods. What comes to mind is something like splitLastPrependingSearch and SplitLastAppendingSearch

src/Illuminate/Support/Str.php Outdated Show resolved Hide resolved
Co-authored-by: Michael Lundbøl <michael.lundboel@gmail.com>
@taylorotwell
Copy link
Member

Agree I don't love passing 'before' or 'after' as strings in that last argument.

@taylorotwell taylorotwell marked this pull request as draft November 14, 2024 15:43
@ash-jc-allen
Copy link
Contributor Author

@morloderex @taylorotwell I completely agree about that last argument. It felt a little bit icky when I was writing it, but I couldn't think what would be the better approach, haha!

@taylorotwell Do you like the idea that @morloderex has proposed about updating the signature to this?:

splitLast($subject, $search, $appendSearch = false, $prependSearch = false)

If so, I'm happy to get that added 😄

I quite like the look of:

[$before, $after] = Str::splitLast('taylor otwell', 'twe', prependSearch: true);
[$before, $after] = Str::splitLast('taylor otwell', 'twe', appendSearch: true);

@ash-jc-allen
Copy link
Contributor Author

Hey! I've gone out on a bit of a whim and made the changes that @morloderex suggested. Hopefully, this looks a bit nicer to use? 🤞😄

@ash-jc-allen ash-jc-allen marked this pull request as ready for review November 20, 2024 17:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants