How can I sort the array returned from File.ReadAllLines in an alphabetical member?
I am reading a CSV file and returning its strings in an array of strings. One of the participants is a manufacturer for which I have Toyota, Ford, etc.
I want to sort an array (maybe another collection) of strings, by value in arbitrary order and alphabetically.
So, I would have:
28437 Ford Fiesta
328 Honda Civic
34949 Toyota Yaris
etc.
What would be the best way to do this with C # and no database? I am not talking databases because I could insert a csv into a table in a sql server database and then query it and return the data. But this data is collected into an html table built on the fly, which will make the database approach a bit long.
source to share
What version of .NET are you using? If you're using 3.5 - or can use C # 3.0 and LINQBridge - then I'll definitely go with LINQ. First convert each row to some suitable object, then use OrderBy:
var cars = lines.Select(line => Car.ParseLine(line))
.OrderBy(car => car.Manufacturer);
source to share
If you just have a group of strings in an array then use
Array.Sort(myArray)
This will put the lines in "myArray" alphabetically (case sensitive).
If you want to do different comparisons (case insensitive for example) you can define your own ICcomparer or use Linq-Extensions, preferably with a lambda expression like
string [] sArray = new string[] { "fsdhj", "FA", "FX", "fxx", "Äbc" };
sArray = sArray.OrderBy(s => s.ToLowerInvariant()).ToArray();
There are a whole bunch of other sorting methods out there, but these are the most basic. I could give you a more detailed answer to your problem if I had a better understanding of what your input object looks like. As long as this is just an array of strings, you should be fine with the above.
In response to the first two comments below, I should also point out that the method for invariant sorting of strings given above is not the best one for this particular job (see comments).
However, it does illustrate the use of extension methods with lambda expressions, which are very handy in situations where you don't have any predefined IComparer classes.
source to share
Without trying to guess John, I believe he is proposing to create a Car class ("some suitable object") with the necessary properties and the ability to fill the car from the line:
public class Car
{
public int Id {get;set;}
public string Manufacturer {get;set;}
public string Model {get;set;}
public static Car ParseLine(string line)
{
string[] parts = line.Split(DELIMITER);
return new Car
{
Id = int.Parse(parts[0]),
Manufacturer = parts[1],
Model = parts[2]
};
}
}
i.e. treating lines as objects. Then with LINQ things get pretty simple:
var query = from line in lines
let car = Car.ParseLine(line)
orderby car.Manufacturer
select car;
var arr = query.ToArray();
Note that you can do this without LINQ, for example (using an array Car[]
) - sorting the array in place:
Array.Sort(arr, (x, y) => string.Compare(x.Manufacturer, y.Manufacturer));
or the same with List<Car>
:
list.Sort((x, y) => string.Compare(x.Manufacturer, y.Manufacturer));
source to share
In John's column, he first analyzes the line for objects and then sorts. You can also just sort the IEnumerable dependent string list based on the part of the string. Below is an example of sorting a list of substrings (first 10 characters starting at position 6):
List<string> lines = new List<string>
{
"34949 Toyota Yaris",
"328 Honda Civic",
"28437 Ford Fiesta"
};
var sortedLines = lines.OrderBy(line => line.Substring(6, 10));
// Or make it case insensitive
// var sortedLines = lines.OrderBy(line => line.Substring(6, 10), StringComparer.InvariantCultureIgnoreCase);
foreach (var line in sortedLines)
{
Console.WriteLine(line);
}
source to share