Sort band names

22

2

Challenge description

You have a music library with many tracks recorded by many bands, each of which has a name, like Queen, Aerosmith, Sunny Day Real Estate, The Strokes . When an audio player displays your library alphabetically by band name, it usually skips the The part, as many band names start with The, making it easier to navigate through your media collection. In this challenge, given a list (array) of strings, you need to sort it that way (that is, omitting the The word at the beginning of the name). You can either write a method or a full working program.

Sample inputs / outputs

[Queen, Aerosmith, Sunny Day Real Estate, The Strokes] -> [Aerosmith, Queen, The Strokes, Sunny Day Real Estate]
[The Ramones, The Cure, The Pixies, The Roots, The Animals, Enrique Iglesias] -> [The Animals, The Cure, Enrique Iglesias, The Pixies, The Ramones, The Roots]
[The The, The They, Thermodynamics] -> [The The, Thermodynamics, The They]

Notes / Edge cases

  • Sorting lexicographically is case insensitive, so The Police, The police and the police are all equivalent,

  • Your algorithm should only omit the first the word, so bands named The The or The The Band are sorted normally by the second the,

  • A band named The (a three letter word) is sorted normally (no skipping),

  • Order of two bands having the same name, one of which starts with the (like The Police and Police) is undefined,

  • You can assume that if a band's name consists of more than one word, they are separated by a single space character. You don't need to handle leading or trailing whitespaces,

  • All input strings match [A-Za-z0-9 ]*, that is they will consist only of lower- and uppercase letters of English alphabet, digits and space characters,

  • Remember that this is a challenge, so make your code as short as possible!

shooqie

Posted 2016-08-02T19:09:20.067

Reputation: 5 032

Do numeral-only names come before or after alphabetical? – AdmBorkBork – 2016-08-02T19:24:09.640

Numeral-only strings come first – shooqie – 2016-08-02T19:42:29.537

1What is the sort order of The and The The? ( Most answers would probably need to change if it is anything other than undefined ) – Brad Gilbert b2gills – 2016-08-03T00:15:40.483

how about Los Lobos? – njzk2 – 2016-08-03T02:26:26.497

3The The is a real band by the way. (along with The Who, The What, The Where, The When, The Why, and The How) – DanTheMan – 2016-08-03T02:33:52.860

If the input had a lowercase the but output an uppercase The, would this be acceptable? – James – 2016-08-03T03:16:15.527

Similar to the "the" / "the the" case, What is the sorting order of "red blues" and "the red blues"? – John Dvorak – 2016-08-03T07:51:01.830

@BradGilbertb2gills: They are the same in this case, so the order is undefined – shooqie – 2016-08-03T07:55:06.757

@njzk2: It's sorted by "Los", since it doesn't start with "the" – shooqie – 2016-08-03T07:55:11.850

@DrGreenEggsandIronMan: Sure – shooqie – 2016-08-03T07:55:17.663

@JanDvorak: Same as "The" and "The The" case, they are treated the same way lexicographically, so the order is undefined. – shooqie – 2016-08-03T07:55:39.320

the pAper chAse is a good edge test case – AdmBorkBork – 2016-08-03T12:55:09.093

Probably want an example that actually uses lowercase letters. – Magic Octopus Urn – 2017-06-13T21:10:39.613

Answers

7

Python, 56 62 64 bytes

lambda b:sorted(b,key=lambda x:(x,x[4:])[x.lower()[:4]=='the '])

Try it

Thanks to @Chris H for pointing out that lstrip() was not handling The The correctly, since the strip was blasting all matching characters and sorting it as a blank string, and @manatwork for finding the flaw in using replace(). The new version should work.

Old version:

lambda b:sorted(b,key=lambda x:x.lower().lstrip('the '))

atlasologist

Posted 2016-08-02T19:09:20.067

Reputation: 2 945

1I'm not convinced. Adding "The animals" to the last list gives ['The The', 'The', 'The Animals', 'Thermodynamics', 'The They']. The 2nd edge case suggest sit should be ['The Animals', 'The The', 'The', 'Thermodynamics', 'The They'] (or swap the 2nd and 3rd items). A little fiddling suggests the space inside strip('the ') is being ignored - try for x in ['The The', 'The They', 'Thermodynamics', 'The', 'The Animals']: print (x.lower().strip('the ')) – Chris H – 2016-08-03T08:54:33.870

That replace() is not much better: 'what the snake'.replace('the ','',1) results 'what snake'. – manatwork – 2016-08-03T11:00:20.883

5

V, 32 28 bytes

ç^The /dwA_
:sort
ç_/$xIThe 

Try it online!

Note to self: Make an abbreviation for :sort so that I don't need 6 whole bytes for a single command!

Explanation:

ç^The /     "On every line starting with 'The ',
       dw   "Delete a word
         A_ "And (A)ppend an underscore '_'

:sort       "Sort all lines alphabetically

ç_/         "On every line containing an underscore,
   $x       "Delete the last character
     IThe   "And prepened 'The '

James

Posted 2016-08-02T19:09:20.067

Reputation: 54 537

Not familiar with V, but it seems this one works fine without the asterisks. Is this coincidence with the input, or actually unneeded? – kirkpatt – 2016-08-02T21:46:58.530

1

@kirkpatt Good idea! That almost works, but not quite. For example, with this input it incorrectly puts "Radiohead" after "The Ramones" and "The Roots". However, that gives me an idea...

– James – 2016-08-02T22:04:54.787

What happens if the is in all lowercase, like the pAper chAse? – AdmBorkBork – 2016-08-03T12:44:25.383

4

Retina, 34 bytes

The trailing linefeed is significant.

%`^
$';
T`L`l`.+;
m`^the 

O`
.+;

I/O is one band per line.

Try it online!

Explanation

%`^
$';

Duplicate each line, using ; as a separator.

T`L`l`.+;

Turn everything in front of a ; to lower case.

m`^the 

Remove any thes that appear at the beginning of a line.

O`

Sort the lines.

.+;

Remove the beginnings of the lines which we used for sorting.

Martin Ender

Posted 2016-08-02T19:09:20.067

Reputation: 184 808

Couldn't you pack the first 3 Steps into a single step? Like in PCRE: s/(?i:the )?(.*)/\L$1\E;$0/ – Falco – 2016-08-03T11:15:45.120

@Falco .NET doesn't support case changes in substitution strings and I haven't yet added them to Retina's custom replacer either. – Martin Ender – 2016-08-03T11:23:21.377

4

Pyke, 16 bytes

.#l1D"the ".^4*>

Try it here!

.#                - sort_by(V, input)
  l1              -  i = i.lower()
      "the ".^    -   i.startswith("the ")
              I   -  if ^:
               4> -   i[4:]

Blue

Posted 2016-08-02T19:09:20.067

Reputation: 26 661

3

Perl, 52 bytes

-13 byte thanks to @manatwork
-1 byte thanks to @msh210

sub f{lc pop=~s/^the //ri}print sort{f($a)cmp f$b}<>

One band per line as input, and so is the output.

The implementation is quite straight forward : the program prints the list of bands, sorted with the help of a custom function (f) which returns the lower case band name without the eventual leading the.

Dada

Posted 2016-08-02T19:09:20.067

Reputation: 8 279

Is shorter with substitution instead of matching: sub f{lc$_[0]=~s/^the //ir}. – manatwork – 2016-08-03T09:08:31.920

1 byte shorter indeed, thanks. – Dada – 2016-08-03T09:18:17.113

Actually I counted either 2 or 3 bytes shorter: no need for both the parenthesis around lc's parameter and the i flag in substitution. Or have you met a test case where that not works? – manatwork – 2016-08-03T10:16:57.143

Thinking again, the amount of command line options could also be reduced if you take each band name on separate line: perl -e 'sub f{lc$_[0]=~s/^the //ri}print sort{f($a)cmp f$b}<>' <<< $'Queen\nAerosmith\nSunny Day Real Estate\nThe Strokes'. – manatwork – 2016-08-03T10:42:57.053

Oh right, I added the parenthesis because =~ as a higher precedence than lc. But the lc is done after the regex so it's ok. But then the i flag is needed if I'm not mistaken. Great idea taking the bands name on separated lines. – Dada – 2016-08-03T11:20:06.853

1Save three bytes: lc pop instead of lc$_[0], and say instead of print. (The latter requires -M5.01, which is free.) Tested in Strawberry 5.20.2 with only the first test case from the question. – msh210 – 2016-08-03T15:59:10.900

Right about the pop, thanks. About the say I thought of it, but it adds a trailing empty line, so I didn't want to use it... – Dada – 2016-08-03T23:17:17.380

2

Python, 66 72 69 bytes

lambda x:sorted(x,key=lambda a:a[4*(a.lower()[:4]=='the '):].lower())

Uses Python's sorted method with the key keyword argument to sort by the name minus "The". This is a lambda; to call it, give it a name by putting f= in front.

Now with extra case insensitivity!

Copper

Posted 2016-08-02T19:09:20.067

Reputation: 3 684

2It doesn't meet the case insensitivity requirement, though... A band name can start with the, in which case this method won't work properly. – shooqie – 2016-08-02T19:21:49.847

@shooqie Oh, I didn't see that requirement. I'll fix it. – Copper – 2016-08-02T19:22:41.347

2

PowerShell v2+, 33 32 29 bytes

$args|sort{$_-replace'^the '}

Saved 3 bytes thanks to @MathiasRJessen

Input is via command-line arguments. Sorts the original names based on the results of the script block {...} that performs a regex -replace to strip out the leading (case-insensitive) "the ".

Examples

PS C:\Tools\Scripts\golfing> .\sort-band-names.ps1 'the Ramones' 'The cure' 'The Pixies' 'The Roots' 'the Animals' 'Enrique Iglesias'
the Animals
The cure
Enrique Iglesias
The Pixies
the Ramones
The Roots

PS C:\Tools\Scripts\golfing> .\sort-band-names.ps1 'The The' 'The They' 'Thermodynamics'
The The
Thermodynamics
The They

PS C:\Tools\Scripts\golfing> .\sort-band-names.ps1 'THE STOOGES' 'The Strokes' 'The The' 'the they' 'the band' 'STP'
the band
THE STOOGES
STP
The Strokes
The The
the they

AdmBorkBork

Posted 2016-08-02T19:09:20.067

Reputation: 41 581

-replace is case-insensitive by default, '^the ' will suffice for the pattern – Mathias R. Jessen – 2016-08-03T10:17:31.587

@MathiasR.Jessen Yes, thanks for the reminder. – AdmBorkBork – 2016-08-03T12:32:18.963

@ValueInk See Mathias' comment about case insensitivity and the final example I added. – AdmBorkBork – 2016-08-03T12:33:23.873

2

JavaScript/ECMAScript 6 93 70 bytes

70 Thanks to Neil and Downgoat for advice

B=>B.sort((a,b)=>R(a).localeCompare(R(b)),R=s=>s.replace(/^the /i,''))

Readable Version for the 70-byte variant

let sortBandNames = (bandNames) => {
    let stripThe = (name) => name.replace(/^the /i, '');
    let compareFunc = (a, b) => stripThe(a).localeCompare(stripThe(b));
    return bandNames.sort(compareFunc)
};

93

f=B=>{R=s=>s.toLowerCase().replace(/the /,'');return B.sort((a,b)=>R(a).localeCompare(R(b)))}

Readable Version for the 93-byte variant

let sortBandNames = (bandNames) => {
    let stripThe = (name) => name.toLowerCase().replace(/the /, '');
    let compareFunc = (a, b) => stripThe(a).localeCompare(stripThe(b));
    return bandNames.sort(compareFunc)
};

Pandacoder

Posted 2016-08-02T19:09:20.067

Reputation: 190

Shouldn't that regexp have a ^ in it? Also, localeCompare is case insensitive on my system, so I didn't need the toLowerCase, just an /i flag on the regexp. Finally you can golf this as follows: B=>B.sort((a,b)=>...,R=s=>...) - sort ignores the extra parameter that sets R. – Neil – 2016-08-02T20:24:12.977

Where in the regex would ^ go? That would be a negation and the the expression is supposed to match and erase "the ". I'll try using locale compare without the lower-case conversion. – Pandacoder – 2016-08-02T22:39:55.120

@Pandacoder the ^ shuold go at the beginning of the regex – Downgoat – 2016-08-02T23:16:16.473

@Downgoat From testing all of the given cases, and a few cases I came up with specifically intending to break the RegEx, with or without the ^ I get no change in behavior, only an extra character that doesn't accomplish anything. – Pandacoder – 2016-08-02T23:52:14.827

@Pandacoder that doesn't make it valid. the ^ is an anchor which requires the "the" to be at the beginning per the spec – Downgoat – 2016-08-02T23:58:32.933

Ah, I see what you mean. Didn't think of sticking "The" in the middle. – Pandacoder – 2016-08-03T00:00:43.603

Updated to include that caret. – Pandacoder – 2016-08-03T00:01:49.987

You can remove the f= as it's ok to return an anonymous function. Also you may be able to save some bytes by mapping to lowercase&replacing the the and use .sort() which is lexicographic by default – Downgoat – 2016-08-03T17:27:12.397

@Downgoat What do you mean by mapping to lowercase (just to make sure, you're looking at the 72/70-byte variant, not the 93/91-byte one)? – Pandacoder – 2016-08-03T19:59:54.370

I meant a=>a.map(i=>i.toLowerCase().replace(/^the /,'')).sort(); but just relized why that doesn't work you can still remove f= and make it just B=>B.sort((a,b)=>R(a).localeCompare(R(b)),R=s=>s.replace(/^the /i,'')) to save 2 bytes – Downgoat – 2016-08-03T20:03:35.390

I feel like there is a way to use map, just as part of the comparator function, but I don't know how to get the lexicographical difference of a two-string array easily. I'll strip the f= though. – Pandacoder – 2016-08-03T20:19:49.977

2

Ruby, 42 bytes

->a{a.sort_by{|s|s.upcase.sub /^THE /,''}}

Try it online!

Value Ink

Posted 2016-08-02T19:09:20.067

Reputation: 10 608

2

Perl 6, 26 bytes

*.sort({fc S:i/^'the '//})

Explanation:

# 「*」 is the input to this Whatever lambda
*.sort(

  # sort based on the return value of this Block lambda
  {
    fc # foldcase the following

    # string replace but not in-place
    S
      :ignorecase
      /
        # at the start of the string
        ^

        # match 「the 」
        'the '

      # replace with nothing
      //
  }
)

Test:

use v6.c;
use Test;

my @tests = (
  « Queen Aerosmith 'Sunny Day Real Estate' 'The Strokes' »
    => « Aerosmith Queen 'The Strokes' 'Sunny Day Real Estate' »,
  « 'The Ramones' 'The Cure' 'The Pixies' 'The Roots' 'The Animals' 'Enrique Iglesias' »
    => « 'The Animals' 'The Cure' 'Enrique Iglesias' 'The Pixies' 'The Ramones' 'The Roots' »,
  « 'The The' 'The They' Thermodynamics »
    => « 'The The' Thermodynamics 'The They' »,
);

# give it a lexical name for clarity
my &band-sort = *.sort({fc S:i/^'the '//});

plan +@tests;

for @tests -> ( :key(@input), :value(@expected) ) {
  is-deeply band-sort(@input), @expected, @expected.perl;
}
1..3
ok 1 - ("Aerosmith", "Queen", "The Strokes", "Sunny Day Real Estate")
ok 2 - ("The Animals", "The Cure", "Enrique Iglesias", "The Pixies", "The Ramones", "The Roots")
ok 3 - ("The The", "Thermodynamics", "The They")

Brad Gilbert b2gills

Posted 2016-08-02T19:09:20.067

Reputation: 12 713

1

Java 8, 178 bytes

void q(String[]s){java.util.Arrays.sort(s,(a,b)->(a.toLowerCase().startsWith("the ")?a.substring(4):a).compareToIgnoreCase(b.toLowerCase().startsWith("the ")?b.substring(4):b));}

Ungolfed version:

void sort(String[] bands) {
    java.util.Arrays.sort(bands, (a, b) -> 
        (a.toLowerCase().startsWith("the ") ? a.substring(4) : a).compareToIgnoreCase(
            b.toLowerCase().startsWith("the ") ? b.substring(4) : b
        )
    );
}

Call as such:

public static void main(String[] args) {
    String[] bands = {"The Strokes", "Queen", "AC/DC", "The Band", "Cage the Elephant", "cage the elephant"};
    sort(bands); // or q(bands) in the golfed version
    System.out.println(java.util.Arrays.toString(bands));
}

Justin

Posted 2016-08-02T19:09:20.067

Reputation: 417

I know you've answered this almost a year ago, but you can golf a few things. Since you state you use Java 8, you can change void q(String[]s){...} to s->{...}. And you can change both (x.toLowerCase().startsWith("the ")?x.substring(4):x) with x.replaceFirst("(?i)the ",""). So the total becomes: s->{java.util.Arrays.sort(s,(a,b)->a.replaceFirst("(?i)the ","").compareToIgnoreCase(b.replaceFirst("(?i)the ","")));} - 118 bytes

– Kevin Cruijssen – 2017-09-18T13:56:16.373

Neat trick with the replaceFirst. When I answered this I had been told a few times on other answers that s->{ ... } wasn't allowed and I had to have a full method signature with types and whatnot. I don't know if that's changed since then. – Justin – 2017-09-18T16:06:35.513

Not sure about back then, but these days it's allowed and used by close to everyone golfing in Java or C# .NET. – Kevin Cruijssen – 2017-09-18T21:14:46.660

0

Vim, 18 bytes

Well now that I realized this is possible, I'm kinda embarrassed by my 26 byte V answer, especially since V is supposed to be shorter than vim. But this is pretty much a builtin.

:sor i/\(The \)*/<CR>

Explanation (straight from vim help):

                            *:sor* *:sort*
:[range]sor[t][!] [b][f][i][n][o][r][u][x] [/{pattern}/]
            Sort lines in [range].  When no range is given all
            lines are sorted.

            With [i] case is ignored.

            When /{pattern}/ is specified and there is no [r] flag
            the text matched with {pattern} is skipped, so that
            you sort on what comes after the match.
            Instead of the slash any non-letter can be used.

James

Posted 2016-08-02T19:09:20.067

Reputation: 54 537

0

C, 216 212 135 + 5 (qsort) = 221 217 140 bytes

M(void*a,void*b){char*A,*B;A=*(char**)a;B=*(char**)b;A=strcasestr(A,"The ")?A+4:A;B=strcasestr(B,"The ")?B+4:B;return strcasecmp(A,B);}

Well, I finally got around to finishing this in C. Golfing tips are very much appreciated.

In this submission, M is the comparison function to be supplied to qsort. Therefore, to invoke this, you must use qsort in the format qsort(argv++,argc--,8,M) where argv contains the command-line arguments and argc is the number of arguments provided.

Try It Online!

R. Kap

Posted 2016-08-02T19:09:20.067

Reputation: 4 730

0

q/kdb+, 36 33 bytes

Solution:

{x(<)@[x;(&)x like"[Tt]he *";4_]}

Example:

q){x(<)@[x;(&)x like"[Tt]he *";4_]}("Queen";"Aerosmith";"Sunny Day Real Estate";"The Strokes";"the Eagles")
"Aerosmith"
"the Eagles"
"Queen"
"The Strokes"
"Sunny Day Real Estate"

Explanation:

Strip out any "[Tt]he " from each input string, sort this list, then sort the original list based on the indexing of the sorted list.

{x iasc @[x;where x like "[Tt]he *";4_]} / ungolfed solution
{                                      } / lambda function
        @[x;                       ;  ]  / apply function to x at indices
                                    4_   / 4 drop, remove first 4 items
            where x like "[Tt]he *"      / where the input matches 'The ...' or 'the ...'
   iasc                                  / returns sorted indices
 x                                       / index into original list at these indices

streetster

Posted 2016-08-02T19:09:20.067

Reputation: 3 635

0

05AB1E, 27 bytes (non-competing)

vyð¡RD¤…TheQsgα£Rðý})‚øí{ø¤

Try it online!

Explanation

vyð¡RD¤…TheQsgα£Rðý})‚øí{ø¤   Argument l
v                 }           For each y in l, do:
 yð¡                            Split y on space
    RD                          Reverse and duplicate
      ¤…TheQ                    Last element equals "The" (true = 1, false = 0)
            sgα                 Absolute difference with length of array
               £                Get elements from index 0 to calculated difference
                R               Reverse
                 ðý             Join on space
                    )‚øí      Pair each element with original
                        {ø¤   Sort and get the original band name

kalsowerus

Posted 2016-08-02T19:09:20.067

Reputation: 1 894

0

Groovy, 34 bytes

{it.sort{it.toLowerCase()-'the '}}

41% my answer is .toLowerCase(), kill me now.


Output

When running...

({it.sort{it.toLowerCase()-'the '}})(['The ramones','The Cure','The Pixies','The Roots','The Animals','Enrique Iglesias'])

The result is...

[The Animals, The Cure, Enrique Iglesias, The Pixies, The ramones, The Roots]

With no debug or error output.

Magic Octopus Urn

Posted 2016-08-02T19:09:20.067

Reputation: 19 422

0

Japt, 11 10 bytes

ñ_v r`^e 

Try it

Shaggy

Posted 2016-08-02T19:09:20.067

Reputation: 24 623

0

Nim, 96 bytes

import algorithm,strutils,future
x=>x.sortedByIt toLower it[4*int(it.toLower[0..3]=="the ")..^0]

Those imports take up so many bytes :|

A translation of my Python answer.

This is an anonymous procedure; to use it, it must be passed into a testing procedure. Here's a full program you can use for testing:

import algorithm,strutils,future
proc test(x: seq[string] -> seq[string]) =
 echo x(@["The The", "The They", "Thermodynamics"]) # Substitute your input here
test(x=>x.sortedByIt toLower it[4*int(it.toLower[0..3]=="the ")..^0])

Copper

Posted 2016-08-02T19:09:20.067

Reputation: 3 684

0

MATL, 16 bytes

tk'^the '[]YX2$S

Input format is (each line corresponds to a test case)

{'Queen', 'Aerosmith', 'Sunny Day Real Estate', 'The Strokes'} 
{'The Ramones', 'The Cure', 'The Pixies', 'The Roots', 'The Animals', 'Enrique Iglesias'}
{'The The', 'The They', 'Thermodynamics'}

Try it online!

Explanation

t        % Implicitly input cell array of strings. Push another copy
k        % Convert to lowercase
'^the '  % String to be used as regex pattern: matches initial 'the '
[]       % Empty array
YX       % Regex replacement: replace initial 'the ' in each string by empty array
2$S      % Sort input according to the modified cell array. Implicitly display

Luis Mendo

Posted 2016-08-02T19:09:20.067

Reputation: 87 464

0

Haskell, 84 bytes

import Data.List
p(t:'h':'e':' ':s)|elem t"Tt"=s
p s=s
sortBy(\a b->p a`compare`p b)

Call with

sortBy(\a b->p a`compare`p b)["The The", "The They", "Thermodynamics"]

Testcase:

let s = sortBy(\a b->p a`compare`p b)
and[s["Queen", "Aerosmith", "Sunny Day Real Estate", "The Strokes"]==["Aerosmith", "Queen", "The Strokes", "Sunny Day Real Estate"],s["The Ramones", "The Cure", "The Pixies", "The Roots", "The Animals", "Enrique Iglesias"]==["The Animals", "The Cure", "Enrique Iglesias", "The Pixies", "The Ramones", "The Roots"],s["The The", "The They", "Thermodynamics"]==["The The", "Thermodynamics", "The They"]]

Laikoni

Posted 2016-08-02T19:09:20.067

Reputation: 23 676

0

C#, 139 Bytes

using System.Linq;System.Collections.IEnumerable S(string[] l)=> l.OrderBy(b=>(b.ToLower().StartsWith("the ")?b.Substring(4):b).ToLower());

Try online!

Without counting the usings the answer would be 102 bytes.

raznagul

Posted 2016-08-02T19:09:20.067

Reputation: 424

I believe you can ignore the final ToLower() due to the case-insensitive requirement – TheLethalCoder – 2016-08-04T15:05:36.377

Also you can make it an anonymous function which should save some bytes: – TheLethalCoder – 2016-08-04T15:07:53.357

l=>l.OrderBy(b=>(b.ToLower().StartsWith("the ")?b.Substring(4):b)); For 67 bytes and then you need to add on the using System.Linq; too – TheLethalCoder – 2016-08-04T15:12:02.597

@TheLethalCoder: I need the second ToLower because of the case-insensitive requirement. Otherwise the order would be case-sensitive. – raznagul – 2016-08-04T15:38:31.807

Okay the point about converting it to an anonymous function still stands though – TheLethalCoder – 2016-08-04T15:42:49.653

0

BASH, 64 Bytes

sed 's/^the / /;s/^The /    /'|sort -fb|sed 's/^ /the /;s/^ /The /'

Input: stdin, one band per line. Output: stdout

Note: The second replacements (s/^The/ / and s/^ /The /) use the tab character, so they don't always copy/paste correctly.

Riley

Posted 2016-08-02T19:09:20.067

Reputation: 11 345

0

Bash + coreutils, 44 bytes

sed '/^the /I!s,^,@ ,'|sort -dk2|sed s,@\ ,,

Explanation: the input and output format is one band per line

sed '/^the /I!s,^,@ ,'   # prepend '@ ' to each line not starting with 'the ', case
                         #insensitive. This adds a temporary field needed by sort.
sort -dk2                # sort in ascending dictionary order by 2nd field onward
sed s,@\ ,,              # remove the temporary field

Test run (using a here-document with EOF as the end marker):

./sort_bands.sh << EOF
> Queen
> Aerosmith
> Sunny Day Real Estate
> The Strokes
> EOF

Output:

Aerosmith
Queen
The Strokes
Sunny Day Real Estate

seshoumara

Posted 2016-08-02T19:09:20.067

Reputation: 2 878

-2

Java 176 158 bytes

public String[]sort(String[]names){
  for(int i=-1;++i<names.length;)
    if(names[i].startsWith("(The |the )"))
      names[i]=names[i].substring(4);
  return Arrays.sort(names,String.CASE_INSENSITIVE_ORDER);
  }

Main Function

public static void main(String[]args){
  Scanner s = new Scanner(System.in);
  List<String> list= new ArrayList<>();
  while(!(String h = s.nextLine).equalsIgnoreCase("~")){
    list.add(h);
  }
System.out.println(sort(list.toArray(newString[0]))

); }

Golfed sort function:

String[]s(String[]n){for(int i=-1;++i<n.length;)if(n[i].startsWith("(The |the )"))n[i]=n[i].substring(4);return Arrays.sort(n,String.CASE_INSENSITIVE_ORDER);}

Thanks to @raznagul for saving 18 bytes

Roman Gräf

Posted 2016-08-02T19:09:20.067

Reputation: 2 915

Doesn't work if a name starts with the. The sort should be case insensitive. – shooqie – 2016-08-02T19:59:12.910

This won't work at all... Strings are immutable. You want to do public String[]sort(String[]names){ for(int i=-1;++i<names.length;) names[i]=names[i].replaceFirst("(the|The)", ""); return Arrays.sort(names,String.CASE_INSENSITIVE_ORDER); } Since the and The should work, and strings a immutable – Socratic Phoenix – 2016-08-02T20:17:36.423

Fixed that, but find me one band that starts with a small "the " – Roman Gräf – 2016-08-03T08:39:26.470

I'm not very good at Java so I might be wrong. But couldn't .replaceFirst... be replaced with .substring(4)? – raznagul – 2016-08-03T10:58:35.987

Yes that's right. I thought replace will edit the String but doesn't. So i missed that while editing last time. – Roman Gräf – 2016-08-03T11:17:18.107

2Arrays.sort returns type void – user902383 – 2016-08-03T13:52:20.487

1

@RomanGräf the pAper chAse

– AdmBorkBork – 2016-08-04T14:07:50.250