3

I have a string with numbers, words, and linebreaks that I split into an Array.

If I run Array.Sort(lines) it will sort the Array numerically by Column 1, Number.

How can I instead sort the Array alphabetically by Column 3, Color?


Note: They are not real columns, just spaces separating the words.

I cannot modify the string to change the results.


| Number     | Name       | Color      |
|------------|------------|------------|
| 1          | Mercury    | Gray       |
| 2          | Venus      | Yellow     |
| 3          | Earth      | Blue       |
| 4          | Mars       | Red        |

C#

Example: http://rextester.com/LSP53065

string planets = "1 Mercury Gray\n"
               + "2 Venus Yellow\n"
               + "3 Earth Blue\n"
               + "4 Mars Red\n";


// Split String into Array by LineBreak
string[] lines = planets.Split(new string[] { "\n" }, StringSplitOptions.None);


// Sort
Array.Sort(lines);


// Result
foreach(var line in lines)
{
    Console.WriteLine(line.ToString());
}

Desired Sorted Array Result

3 Earth Blue
1 Mercury Gray
4 Mars Red
2 Venus Yellow

3 Answers 3

4

Try this code:

string planets = "1 Mercury Gray \n"
                    + "2 Venus Yellow \n"
                    + "3 Earth Blue \n"
                    + "4 Mars Red \n";

var lines = planets.Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
    .OrderBy(s => s.Split(' ')[2])
    .ToArray();

foreach (var line in lines)
{
    Console.WriteLine(line);
}

EDIT: Thanks @Kevin!

Sign up to request clarification or add additional context in comments.

2 Comments

It's working. Let me test it on my project and see what other people have to say. I will get back to you, thanks.
Aleks, the code's a bit more complicated than it needs to be. You're splitting the line into an array, ordering it, and then reassembling - when all you need to do is: .OrderBy(s => s.Split(' ')[2]);
2

Aleks has got the straight-up answer - I just wanted to contribute something from another angle.

This code is fine from an academic, just learning the concepts point of view.

But if you're looking to translate this into something for business dev, you should get in the habit of structuring it like:

  • Develop a Planet class
  • Have a function that returns a Planet from a source text line
  • Have a function that displays a Planet how you intend it to be displayed.

There are a lot of reasons for this, but the big one is that you'll have reusable, flexible code (look at the function you're writing right now - how likely is it that you'll be able to reuse it down the line for something else?) If you're interested, look up some info on SRP (Single Responsibility Principle) to get more info on this concept.

This is a translated version of your code:

    static void Main(string[] args)
    {
        string planetsDBStr = "1 Mercury Gray \n"
                + "2 Venus Yellow \n"
                + "3 Earth Blue \n"
                + "4 Mars Red \n";

        List<Planet> planets = GetPlanetsFromDBString(planetsDBStr);

        foreach (Planet p in planets.OrderBy(x => x.color))
        {
            Console.WriteLine(p.ToString());
        }
        Console.ReadKey();

    }

    private static List<Planet> GetPlanetsFromDBString(string dbString)
    {
        List<Planet> retVal = new List<Planet>();
        string[] lines = dbString.Split("\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
        foreach (string line in lines)
            retVal.Add(new Planet(line));
        return retVal;
    }

    public class Planet
    {
        public int orderInSystem;
        public string name;
        public string color;
        public Planet(string databaseTextLine)
        {
            string[] parts = databaseTextLine.Split(' ');
            this.orderInSystem = int.Parse(parts[0]);
            this.name = parts[1];
            this.color = parts[2];
        }
        public override string ToString()
        {
            return orderInSystem + " " + name + " " + color;
        }
    }

EDIT: Fixed some formatting issues

Comments

0

You can use an Array.Sort overload that takes the custom comparer:

public class MyComparer : IComparer  {
      int IComparer.Compare( Object x, Object y )  {
          //compare last parts here
      }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.