Sorting List<String> in C#

How can I order a Liststring?

ListaServizi = ListaServizi.OrderBy(q => q).ToList();

How to sort a list of lists of strings

The default call to pChain.Sort() can't predict that you want to sort by the first element, you need to explicity specify that:

pChain.Sort((x, y) => String.Compare(x.FirstOrDefault(), y.FirstOrDefault()));

Alternatively you can use Linq's OrderBy (which is a stable sort as per the documentation):

pChain = pChain.OrderBy( x => x.FirstOrDefault()).ToList();

This method performs a stable sort; that is, if the keys of two
elements are equal, the order of the elements is preserved. In
contrast, an unstable sort does not preserve the order of elements
that have the same key.

Sorting ListString in C#

How about:

    list.Sort((x, y) =>
{
int ix, iy;
return int.TryParse(x, out ix) && int.TryParse(y, out iy)
? ix.CompareTo(iy) : string.Compare(x, y);
});

C# - Sort list of strings by instances of a specified character?

Using a class is possible indeed but with linq you can ask yourself if it's really required

List<string> listOfNames = new List<string>();
listOfNames.Add("bob");
listOfNames.Add("bret");
listOfNames.Add("amy");
listOfNames.Add("lee");

// sort the string by the count of character of B or b
var sorted = listOfNames.OrderBy(name => name.Count(c => c == 'b' || c == 'B')).ToList();

Sort List of C# object by STRING parameter

Add reference to nuget package:

https://www.nuget.org/packages/System.Linq.Dynamic/

  1. Add using System.Linq.Dynamic; at the top.
  2. Use var usersSorted = users.AsQueryable().OrderBy("firstname ASC").ToList();

Sort ListListstring by a certain 'column'

This code has no columns, it's a list that contains lists. LINQ can still order the results. The methods that order results in LINQ are OrderBy() and OrderByDescending(). Its argument is a lambda that produces the ordering key.

In this case, the lambda should return the list item that should be used for ordering, eg :

var  _optoGrid = new List<List<string>>{
new List<string> {"10", "10", "100", "20", "10", "10"},
new List<string> {"20", "20", "50", "10", "1546", "555"},
new List<string> {"30", "30", "10", "10", "10", "100"},
new List<string> {"30", "30", "10", "1", "10", "100"}
};
var orderedResults=_optoGrid.OrderBy(lst=>lst[5]);

Or

var orderedResults=_optoGrid.OrderByDescending(lst=>lst[5]);

That's very fragile code though. Nothing guarantees that all lists have the same number of items. It's very easy to forget one value or enter one more. .OrderBy(lst=>lst[5]) will throw if one list contains fewer than 6 items but won't complain if the wrong number of items are used.

It would be better if a proper class was used instead of lists, especially if all items are expected to have the same number of items, eg :

class MyItem
{
public string ProperlyNamedProperty1{get;set;}
...
public MyItem(string prop1,string prop2,...)
{
ProperlyNamedProperty1=prop1;
...
}
}

var _optoGrid = new List<MyItem>{
new MyItem("10", "10", "100", "20", "10", "10"),
};
var orderedResults=_optoGrid.OrderBy(item=>item.Property6);

Value tuples can also be used if the list is only going to be used locally, eg in a single method. Of course, 6 properties are a bit too much :

var  _optoGrid = new List<(string prop1, string prop2, string prop3, string prop4, string prop5, string prop6)>{
("10", "10", "100", "20", "10", "10"),
("20", "20", "50", "10", "1546", "555"),
("30", "30", "10", "10", "10", "100"),
("30", "30", "10", "1", "10", "100")
};
var orderedResults=_optoGrid.OrderBy(tuple=>tuple.prop6);

If one is feeling very lazy and the number of items isn't that greate, the names can be ommited:

var  _optoGrid = new List<(string, string, string, string, string, string)>{
("10", "10", "100", "20", "10", "10"),
("20", "20", "50", "10", "1546", "555"),
("30", "30", "10", "10", "10", "100"),
("30", "30", "10", "1", "10", "100")
};
var orderedResults=_optoGrid.OrderBy(tuple=>tuple.Item6);

The nice thing about tuples is they are strongly typed. There's no reason to use the same type for all of them, eg :

var  _optoGrid = new List<(int, int, string, string, string, double)>{
(10, 10, "100", "20", "10", 10),
(20, 20, "50", "10", "1546", 555),
(30, 30, "10", "10", "10", 100),
(30, 30, "10", "1", "10", 100)
};
var orderedResults=_optoGrid.OrderBy(tuple=>tuple.Item6);

This avoids another thorny issue, that of lexicographical ordering. If I change a string from "10" to "1000" it will *still* appear before "555", because words that start with"1"always come before words that start with"5". Using strings, OrderBy will return :

10 10 100 20 10   10000 
20 20 50 10 1546 555

Ooops.

Using an int or double for the sixth field though, we get the expected order :

20 20  50 10 1546   555 
10 10 100 20 10 10000

Sort list of string arrays c#

You can use LINQ:

animalList = animalList
.OrderBy(arr => arr[0])
.ThenBy(arr => arr[1])
.ToList();

Your sample:

List<string[]> animalList = new List<String[]>{ 
new []{"Dog", "Golden Retriever", "Rex"},
new []{"Cat", "Tabby", "Boblawblah"},
new []{"Fish", "Clown", "Nemo"},
new []{"Dog", "Pug", "Daisy"},
new []{"Cat", "Siemese", "Wednesday"},
new []{"Fish", "Gold", "Alaska"}
};

Result:

-       [0] {string[3]} string[]
[0] "Cat" string
[1] "Siemese" string
[2] "Wednesday" string
- [1] {string[3]} string[]
[0] "Cat" string
[1] "Tabby" string
[2] "Boblawblah" string
- [2] {string[3]} string[]
[0] "Dog" string
[1] "Golden Retriever" string
[2] "Rex" string
- [3] {string[3]} string[]
[0] "Dog" string
[1] "Pug" string
[2] "Daisy" string
- [4] {string[3]} string[]
[0] "Fish" string
[1] "Clown" string
[2] "Nemo" string
- [5] {string[3]} string[]
[0] "Fish" string
[1] "Gold" string
[2] "Alaska" string

How Sort A Liststring By A Part Of That String Desc

Asc:

list_lines = list_lines.OrderBy(s => int.Parse(s.Split(Separator, StringSplitOptions.None)[4])).ToList();

Desc:

list_lines = list_lines.OrderByDescending(s => int.Parse(s.Split(Separator, StringSplitOptions.None)[4])).ToList();

Sort a list alphabetically

You can sort a list in-place just by calling List<T>.Sort:

list.Sort();

That will use the natural ordering of elements, which is fine in your case.

EDIT: Note that in your code, you'd need

_details.Sort();

as the Sort method is only defined in List<T>, not IList<T>. If you need to sort it from the outside where you don't have access to it as a List<T> (you shouldn't cast it as the List<T> part is an implementation detail) you'll need to do a bit more work.

I don't know of any IList<T>-based in-place sorts in .NET, which is slightly odd now I come to think of it. IList<T> provides everything you'd need, so it could be written as an extension method. There are lots of quicksort implementations around if you want to use one of those.

If you don't care about a bit of inefficiency, you could always use:

public void Sort<T>(IList<T> list)
{
List<T> tmp = new List<T>(list);
tmp.Sort();
for (int i = 0; i < tmp.Count; i++)
{
list[i] = tmp[i];
}
}

In other words, copy, sort in place, then copy the sorted list back.


You can use LINQ to create a new list which contains the original values but sorted:

var sortedList = list.OrderBy(x => x).ToList();

It depends which behaviour you want. Note that your shuffle method isn't really ideal:

  • Creating a new Random within the method runs into some of the problems shown here
  • You can declare val inside the loop - you're not using that default value
  • It's more idiomatic to use the Count property when you know you're working with an IList<T>
  • To my mind, a for loop is simpler to understand than traversing the list backwards with a while loop

There are other implementations of shuffling with Fisher-Yates on Stack Overflow - search and you'll find one pretty quickly.



Related Topics



Leave a reply



Submit