【问题标题】:Sort list alphabetically by all columns in C# using linq (if possible)使用 linq 按 C# 中所有列的字母顺序对列表进行排序(如果可能)
【发布时间】:2017-11-30 20:04:17
【问题描述】:

我有一个包含城市名称和城市国家的城市列表,我想使用 LinQ 按所有列排序,匹配过滤器。

例如:

CITY_NAME    | CITY COUNTRY  
-------------+---------------
Buenos Aires | Argentina  
Asuncion     | Paraguay  
Sydney       | Australia  
Abadeh       | Iran  
Acero        | Bolivia

我想通过匹配 .StartsWith 的“A”字母但考虑所有列,但首先是 City_Country 然后是 City_Name 并按字母顺序排序,从而获得一个列表。

结果应该是:

Buenos Aires | Argentina  
Sydney       | Australia  
Abadeh       | Iran  
Acero        | Bolivia  
Asuncion     | Paraguay  

这个:

.OrderBy(city => city.CITY_COUNTRY).ThenBy(city => city.CITY_NAME)

不起作用,因为先按国家/地区排序,然后按名称排序,我会得到如下结果:

Buenos Aires | Argentina  
Sydney       | Australia  
Acero        | Bolivia  
Abadeh       | Iran  
Asuncion     | Paraguay 

这是错误的,因为 Abadeh |伊朗比 Acero 更匹配 |玻利维亚。

我尽量说清楚。

谢谢

【问题讨论】:

  • 我没有时间给出一个完整的答案(而且我没有测试,所以它不够充实,不能成为一个),但它应该会让你朝着正确的方向前进。 Cities.Select(city => new Tuple<string, City>(city.CITY_NAME)).Union(Cities.Select(city => new Tuple<string, City>(city.CITY_COUNTY)).OrderBy(item => item.Item1).Select(item => item.Item2).Distinct()。最后的Distinct() 是症结所在,LINQ to Objects 保持秩序,其他 LINQ 提供者可能不会。
  • “匹配得更好”是什么意思?两者都以“A”开头。 “字母顺序”是什么意思?对于哪一列或几列?为什么“澳大利亚悉尼”排在“伊朗阿巴德”之前? “澳大利亚”应该在“阿巴德”之后?
  • 如果城市是新西兰国家的惠灵顿,@RodriFerry 应该出现在哪里?还是根本不应该出现(因为它不是以A开头)?
  • 这些解决方案中的任何一个对您有用吗@RodriFerry?

标签: c# linq sorting sql-order-by


【解决方案1】:

我从 lambda 语法切换到查询理解,以便更轻松地缓存 StartsWith 结果:

var ans = from city in Cities
          let countrysw = city.COUNTRY_NAME.StartsWith("A")
          let citysw = city.CITY_NAME.StartsWith("A")
          where countrysw || citysw
          orderby citysw,(countrysw ? city.COUNTRY_NAME : city.CITY_NAME)
          select city;

基本上,您会测试以匹配开头的国家和城市,然后首先按国家匹配(假排序在真之前)然后按匹配名称对这些匹配进行排序。

【讨论】:

  • OP 说 Country over City 所以我猜它会在这些国家中排序为“澳大利亚”。
  • 为什么会这样。
  • @mjwills 我重新编写了查询以正确选择/排序。
【解决方案2】:

ThenBy 仅当您在同一个国家/地区有两个城市时才会有任何区别,因为它先对国家/地区进行排序,然后对这些国家/地区内的城市进行排序

例如,如果您的列表中还有澳大利亚珀斯,那么您最终会得到:

Buenos Aires | Argentina
Perth | Australia
Sidney | Australia
Acero | Bolivia
Abadeh | Iran
Asuncion | Paraguay

如果您想按城市或国家/地区值中的哪一个进行排序,那么您可以尝试以下操作:

.OrderBy(city => string.Compare(city.CITY_COUNTRY, city.CITY_NAME) < 0 ? city.CITY_COUNTRY : city.CITY_NAME)

我认为这将为您提供您期望的列表。

【讨论】:

  • 假设搜索的是字母“B”而不是“A”(因此 OP 会希望 Buenos Aires 作为结果中的第一行)。这段代码会这样做吗?
  • 不完全是。我的代码只使用字母表中的第一个值(城市或国家名称)。但是如果你想使用特定的字母,它可以很容易地修改。
【解决方案3】:

我怀疑您需要投影一个包含 either CityCountry 的新列(取决于它是否与 "A" 前缀匹配),然后按 排序该新列。一种可能的方法是:

using System;
using System.Collections.Generic;
using System.Linq;

namespace TestConsole
{
    public class Program
    {
        public class CountryAndCity
        {
            public string Country { get; set; }
            public string City { get; set; }
        }

        static void Main(string[] args)
        {
            var cities = new List<CountryAndCity>
            {
                new CountryAndCity() {Country = "Australia", City = "Sydney"},
                new CountryAndCity() {Country = "Argentina", City = "Buenos Aires"},
                new CountryAndCity() {Country = "Paraguay", City = "Asuncion"},
                new CountryAndCity() {Country = "Abadeh", City = "Iran"}
            };

            // The important bit starts here
            var results = cities
                .Where(z => z.Country.StartsWith("A") || z.City.StartsWith("A")) // this line is optional (only needed if you want to remove those that don't start with A
                .Select(z =>
                    new
                    {
                        OriginalData = z,
                        Match = z.Country.StartsWith("A") ? z.Country : z.City.StartsWith("A") ? z.City : "ZZZZZZ"
                    })
                .OrderBy(z => z.Match)
                .Select(z => z.OriginalData);
            // The important bit ends here

            Console.WriteLine(string.Join("\r\n", results.Select(z => $"{z.Country}-{z.City}")));

            Console.ReadLine();
        }
    }
}

【讨论】:

    猜你喜欢
    • 2013-05-02
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 2021-11-20
    相关资源
    最近更新 更多