0

How does one order a list of classes by a dictionary key within the class eg...

List<City> cities;

Public Class City
{
    public Dictionary<string, string> CityAttributes;
}

In this scenario, I want to order the cities list by a particular string in the dictionary CityAttributes.

eg London Paris New York

Each city has a CityAttribute dictionary...

<"Population over 6 million", "Yes">
<"Radius more than 15 miles", "No">
<"Currency","Euro">

I want to order the cities by Currency. The resulting list would be: New York Paris London

insanepaul
  • 187
  • 2
  • 5
  • 17
  • you mean by a specific value in that dictionary? – adjan Oct 16 '18 at 14:51
  • Well, that is a dictionary. How you want to order by a complete dictionary that contains multiple keys and values? You should tell us more about the logic. It's the same as saying i want to sort cities by their residents, not very meaningful without additional informations. In this case it would be useful to sort cities by their population, so in your sample you could use `someClass.OrderBy(x => x.SomeProperty.Count)`. – Tim Schmelter Oct 16 '18 at 14:51
  • Do you want to use lambda to firstly order the dictionary and then use projection to project that into someClass? – nick gowdy Oct 16 '18 at 14:53
  • Order by SomeProperty's item count? By its HashCode? We need more information on this. – Bas Oct 16 '18 at 14:55
  • Have you considered using a [SortedDictionary](https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.sorteddictionary-2?view=netframework-4.7.2)? – Rui Jarimba Oct 16 '18 at 14:55
  • Your code is not valid C# code. – dymanoid Oct 16 '18 at 14:55
  • Possible duplicate of [c# sort dictionary with linq](https://stackoverflow.com/questions/5949904/c-sharp-sort-dictionary-with-linq) – Rui Jarimba Oct 16 '18 at 15:03
  • Hi, thanks for the feedback. I've edited it to make it much more understandable using cities – insanepaul Oct 16 '18 at 15:22
  • @Adrian Yes...sorting the list by the value of a specific key – insanepaul Oct 16 '18 at 15:25

2 Answers2

3

You use Linq's Orderby like this:

cities.OrderBy(city => city.CityAttributes["Currency"]);

If you don't want to use a lambda, but something more readable, you can also do this:

var orderedCities = from city in cities
                    orderby city.CityAttributes["Currency"]
                    select city;

Edit: A good place to get started reading up on linq is https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/.

Bas
  • 1,946
  • 21
  • 38
  • That's not an error message. Try expanding the Results view. – Bas Oct 16 '18 at 15:31
  • I'm using your answer on the actual code... model.VacancyList.OrderBy(model.VacancyList => model.VacancyList.CustomAttributes["Is a company car required for this role?"]); ...however tI get syntax error ',' expected – insanepaul Oct 16 '18 at 15:31
  • That message means that the query to order your cities hasn't actually run yet. It's called Deferred Execution. It will run as soon as someone (or some thing) starts looking at the results - like by expanding the results view. If you want to see the results without having to expand a Results view, use cities.OrderBy(city => city.CityAttributes["Currency"]).ToList(); – Bas Oct 16 '18 at 15:33
  • Try this: model.VacancyList.OrderBy(v => v.CustomAttributes["Is a company car required for this role?"]).ToList(); – Bas Oct 16 '18 at 15:34
  • ok, i used the ToList() but still get Syntax error, ',' expected – insanepaul Oct 16 '18 at 15:35
  • That seems to work! model.VacancyList.OrderBy(v => v.CustomAttributes["Is a company car required for this role?"]).ToList(); Thanks! – insanepaul Oct 16 '18 at 15:36
0

You can sort it the below way saying OrderBy to order with the CityAttributes value

cityList.Select(k => k.CityAttributes.OrderBy(x => x.Value)).ToList();

Your case,

public static void Main()
{       
    var cityAttrib1 = new Dictionary<string, string>()
    {
        { "1", "Capital City"},
        { "2", "High Population"},
        { "3", "Good Transportation"}
    };

    var cityAttrib2 = new Dictionary<string, string>()
    {
        { "1", "Not a Capital City"},
        { "2", "Low Population"},
        { "3", "Poor Transportation"}
    };

    var city1 = new City { CityAttributes = cityAttrib1 };
    var city2 = new City { CityAttributes = cityAttrib2 };

    var list = new List<City> { city1, city2 };

    var sortedList = list.Select(k => k.CityAttributes.OrderBy(x => x.Value)).ToList();

    //Print the sorted output
    foreach(var item in sortedList)
    {
        foreach(KeyValuePair<string, string> entry in item)
        {
                Console.WriteLine(entry.Value); 
        }
        Console.WriteLine(Environment.NewLine);
    }
}

public class City
{
    public Dictionary<string, string> CityAttributes { get; set; }
}
Hary
  • 5,690
  • 7
  • 42
  • 79