0

This is example code.

I have string with the names of planets, their order, and color, separated by spaces and NewLines.

I do not want to modify the string to change the results.


I want to create 3 Lists, Order, Name and Color from the string.

| Order      | Name       | Color      |
|------------|------------|------------|
| First      | Mercury    | Gray       |
| Second     | Venus      | Yellow     |
| Third      | Earth      | Blue       |
| Fourth     | Mars       | Red        |

This will create a List from the string, split by NewLine.

string planets = "First Mercury Gray" 
                + Environment.NewLine 
                + "Second Venus Yellow"
                + Environment.NewLine
                + "Third Earth Blue"
                + Environment.NewLine 
                + "Fourth Mars Red"
                + Environment.NewLine;


List<string> PlanetOrder = planets.Split(
               new[] { Environment.NewLine }, StringSplitOptions.None).ToList();   

List<string> PlanetName = planets.Split(
               new[] { Environment.NewLine }, StringSplitOptions.None).ToList();

List<string> PlanetColor = planets.Split(
               new[] { Environment.NewLine }, StringSplitOptions.None).ToList();

But within each line how can I also Split by space and choose word [1]Order, [2]Name, [3]Color?

planets.Split(' ')[2]; //Name
0

3 Answers 3

6

You can do the following. First split the string by Environment.NewLine, then split each line of the result by space and add the items to the different lists.

string planets = "First Mercury Gray"
            + Environment.NewLine
            + "Second Venus Yellow"
            + Environment.NewLine
            + "Third Earth Blue"
            + Environment.NewLine
            + "Fourth Mars Red"
            + Environment.NewLine;

List<string> PlanetOrder = new List<string>();
List<string> PlanetName = new List<string>();
List<string> PlanetColor = new List<string>();
string[] lines = planets.Split(new string[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in lines)
{
    string[] arr = line.Split(' ');
    PlanetOrder.Add(arr[0]);
    PlanetName.Add(arr[1]);
    PlanetColor.Add(arr[2]);
}
Sign up to request clarification or add additional context in comments.

6 Comments

Thanks, I am trying it in my project. I will get back to you.
Your solution worked. I am comparing with Xavave's answer for speed because in my real program I apply this solution to a very long list with many splits.
That's ok :), but i recommend to make a test with a long list with both solutions. I disagree with Xavaeve's answer about the performance.
Nothing is wrong, but he is splitting every string three times, but necessary is only one time and I think that converting the splitted lines to List is slower than using the string array. I did a test of both alogrithms and had a different result than him about the performance. See for yourself and test both algorithms and let us know what your result is
I tested both solutions with the real list on rextester. I looked at the absolute running time and cpu time. Both performed within milliseconds of each other. Each sometimes slower, sometimes faster. His performs just as fast, maybe it has to do with the compiler. I will use yours so to not split more than necessary.
|
2

A LINQ approach:

public enum PlanetColumn
{
    Order = 0,
    Name = 1,
    Color = 2
}

string planets = "First Mercury Gray" 
            + Environment.NewLine 
            + "Second Venus Yellow"
            + Environment.NewLine
            + "Third Earth Blue"
            + Environment.NewLine 
            + "Fourth Mars Red"
            + Environment.NewLine;

var lookup = planets
    .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries)
    .SelectMany(p => p.Trim().Split(' ').Select((value, colIndex) => new { Column = (PlanetColumn) colIndex, Value = value} ))
    .ToLookup(prop => prop.Column, prop => prop.Value);

var planetOrders = lookup[PlanetColumn.Order].ToList();
var planetNames = lookup[PlanetColumn.Name].ToList();
var planetColors = lookup[PlanetColumn.Color].ToList();

Note: I added the enum declaration just because it looks cleaner, you can do it with the integer value directly (and use lookup[0], lookup[1], and lookup[2])

4 Comments

A good example of how not every problem is a nail, desperate to be pounded by the hammer that is LINQ :)
Well, it depends on input size and what you are going to do next... but yeah, it's probably too much overhead for common scenarios, and the OP would probably need 3 HashSet<string> instances instead of 3 lists if he's going to search for strings in the collections a few times... but hey, I'm an ILookup fanboy :D
PS, I meant no disrespect to the technical brilliance of your answer, simply to comment that this, IMHO, is one of those situations where the simple loop approach wins out for simplicity, readability, maintain-ability, performance, self-documentation .. etc :)
No offense taken :)
1

or with Linq foreach :

        List<string> planetOrder = new List<string>();
        List<string> planetName = new List<string>();
        List<string> planetColor = new List<string>();
       planets.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).ToList().ForEach(p =>
        {
            planetOrder.Add(p.Split(new[] { ' ' })[0]);
            planetName.Add(p.Split(new[] { ' ' })[1]);
            planetColor.Add(p.Split(new[] { ' ' })[2]);
        });

7 Comments

I've updated the code so it's in 1 line ; execution time for lookup solution : 70893 ticks, Ben's answer :2097 ticks, for mine : 1999 ticks
Thanks, I will look all these over.
This worked well. It is the fastest solution out of the answers?
I've tested speed and the answer is yes
Are you sure? Because you are doing more split operations. How did you tested this? Stopwatcher?
|

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.