Preserve Line Breaks During Sort

551 Views Asked by At

This isn't necessarily PHP-specific, although I'm using PHP. I guess I'm looking for a creative solution.

Say I have a list of terms in a textarea that are separated by an extra new line, for instance:

Cookie

Apple

Banana

I want to sort() these terms and display them after page submit, so that the results look like:

Apple

Banana

Cookie

and not like

Apple
Banana
Cookie

(which would be preceded by two blank lines)

Anyone have any suggestions on how that might be possible?

Sorry, I should have been more clear. The list in the textarea is entered by a user so it may or may not already contain extra newlines.

3

There are 3 best solutions below

0
AbraCadaver On BEST ANSWER

If there are always two newlines, then it's as easy as splitting, sorting and joining:

$result = explode("\n\n", $text);
sort($result);
$result = implode("\n\n", $result);

If it could be one or more newlines then:

preg_match_all("/^(.+$)(\n+)?/m", $text, $matches);

sort($matches[1]);

$result = '';
foreach($matches[1] as $key => $val) {
    $result .= $val . $matches[2][$key];
}
  • Match all line text $matches[1] and the terminating newlines (if any) $matches[2]
  • Sort the line text array $matches[1]
  • Loop the line text array $matches[1] and add the corresponding newlines (if any) $matches[2]
0
Joseph Ryle On

Including the newlines, every array should have an odd number of elements, so the integer value of array.length / 2 should always yield the number of newlines, and should also yield the index of the first word in a 0-indexed language.

For the number of words in the array (i.e. from array.length / 2 to the end of the array, exclusive), you could print the word and print whatever is at the word's index - the array.length / 2, which should be a newline, until the last word. The newline should not be printed afterward if the index is of the last word.

0
coderodour On

You can accomplish this by first using PHP's built in explode() function to get an array out of your string in your text area, using the 2 newline characters between the list items (one to move to new line from the line where there is actual text, and one for the blank line after) as the delimiter to explode on. Sort that array and then reconstruct your string out of it, manually adding back the new lines.

The function below demonstrates how this is achieved and MAY be DIRECTLY applicable to your needs, else guide you in the right direction:

function sort_list_with_line_breaks($list_string){

  $return_list = '';

  // Break the string on newline followed by blank line into array
  $list_array = explode("\n\n", $list_string);

  // Apply your sorting
  sort($list_array);

  // Reconstruct string
  $count = 0;
  foreach($list_array as $string){
      if($count == count($list_array)){ break; }
      if($count != 0){ $return_list .= "\n\n"; }
      $return_list .= $string;
      $count++;
  }

  return $return_list;
}