Skip to content

Instantly share code, notes, and snippets.

@BenMakesGames
Last active September 16, 2024 19:57
Show Gist options
  • Save BenMakesGames/9042fc01a2bb95472341071b6794dad1 to your computer and use it in GitHub Desktop.
Save BenMakesGames/9042fc01a2bb95472341071b6794dad1 to your computer and use it in GitHub Desktop.

Use Case

Pseudo code:

output = "some@kind@of@weird@input".split('@')[0];

A couple possible responses you might have to seeing this kind of code a lot in the codebase you're working on:

  1. "Well this is a code-smell! How can I refactor the code to not put us in this situation all the time? (And who the heck thought to do @-separated strings??)"
  2. "Well that's not the most readable way to express that operation... and it creates an additional allocation! Surely there a better way??"

I can't help you with #1, unfortunately... but here's one possible way to answer #2:

JavaScript

/**
 * Returns the input string after removing the first instance of the separator and everything after it.
 * 
 * If the separator is not found, the original string is returned.
 */
String.prototype.trimAfterFirst = function(separator) {
    const separatorIndex = this.indexOf(separator);

    if(separatorIndex < 0) return this;

    return this.substring(0, separatorIndex);
};

Example Usage

const value = "this|that|the other".trimAfterFirst("|");

console.log(value); // "this"

C#

Two versions: one that takes a string separator (and a StringComparison), and another that just takes a char separator.

public static class TrimAfterFirstExtension
{
    /// <summary>
    /// Returns the input string after removing the first instance of the separator and everything after it.
    /// 
    /// If the separator is not found, the original string is returned.
    /// </summary>
    public static string TrimAfterFirst(this string input, string separator, StringComparison comparisonType = StringComparison.CurrentCulture)
    {
        var separatorIndex = input.IndexOf(separator, comparisonType);

        if(separatorIndex < 0) return input;

        return input[..separatorIndex];
    }
    
    /// <summary>
    /// Returns the input string after removing the first instance of the separator and everything after it.
    /// 
    /// If the separator is not found, the original string is returned.
    /// </summary>
    public static string TrimAfterFirst(this string input, char separator)
    {
        var separatorIndex = input.IndexOf(separator);

        if(separatorIndex < 0) return input;

        return input[..separatorIndex];
    }
}

Example Usage

var value = "this$that$the other".TrimAfterFirst('$');

Console.WriteLine(value); // "this"

Final Thoughts

What do you think about the name "trim after first X"? The name feels a little ambiguous to me - like, does that mean the first "X" found is included, or not?

  • Maybe there's a better name? "take until first X", or something??
  • Maybe just do the refactor to not put yourself in this position in the first place???
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment