SortByCustomOrder 根据指定的顺序对任意类型的列表进行排序

static List<T> SortByCustomOrder<T, TKey>(
    List<T> items,
    List<TKey> order,
    Func<T, TKey> keySelector)
{
    // 将排序顺序转换为字典
    var orderIndex = order
        .Select((x, index) => new { Value = x, Index = index })
        .ToDictionary(x => x.Value, x => x.Index);

    // 使用字典进行排序
    return items
        .OrderBy(item => orderIndex.TryGetValue(keySelector(item), out int index) ? index : int.MaxValue)
        .ToList();
}

参数说明
  1. List<T> items: 要排序的对象列表,其中 T 是对象的类型。
  2. List<TKey> order: 定义排序顺序的列表,其中 TKey 是排序键的类型。
  3. Func<T, TKey> keySelector: 一个函数,用于从每个对象中提取用于排序的键。
逻辑步骤
  1. 创建排序顺序字典:

    • 通过 Select 方法和 ToDictionary 方法,将 order 列表转换为一个字典 orderIndex,字典的键是排序值,值是它们的索引。这样可以快速查找每个排序键的优先级。
  2. 排序:

    • 使用 LINQ 的 OrderBy 方法,根据 orderIndex 字典中的索引对 items 进行排序。如果某个键不在字典中,则返回 int.MaxValue,确保这些项在排序结果中排到最后。

使用案例:

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

public class ProductData
{
    public string DepartmentId { get; set; }
}

public class ParkMill
{
    public List<string> DepartmentCode { get; set; }
}

public class Request
{
    public ParkMill parkMill { get; set; }
}

class Program
{
    static void Main()
    {
        var request = new Request
        {
            parkMill = new ParkMill
            {
                DepartmentCode = new List<string> { "B", "A", "C", "D" }
            }
        };

        var productDatas = new List<ProductData>
        {
            new ProductData { DepartmentId = "C" },
            new ProductData { DepartmentId = "A" },
            new ProductData { DepartmentId = "D" },
            new ProductData { DepartmentId = "B" },
            new ProductData { DepartmentId = "E" } // E 不在 DepartmentCode 中
        };

        // 调用通用的排序方法
        var sortedProductDatas = SortByCustomOrder(productDatas, request.parkMill.DepartmentCode, p => p.DepartmentId);

        foreach (var product in sortedProductDatas)
        {
            Console.WriteLine(product.DepartmentId);
        }
    }

    // 通用排序方法
    static List<T> SortByCustomOrder<T, TKey>(
        List<T> items,
        List<TKey> order,
        Func<T, TKey> keySelector)
    {
        // 将排序顺序转换为字典
        var orderIndex = order
            .Select((x, index) => new { Value = x, Index = index })
            .ToDictionary(x => x.Value, x => x.Index);

        // 使用字典进行排序
        return items
            .OrderBy(item => orderIndex.TryGetValue(keySelector(item), out int index) ? index : int.MaxValue)
            .ToList();
    }
}

AtCoder 王国を治める高橋君は、英小文字のアルファベット順を変更することにしました。 新たなアルファベット順はa , b , …, z を並べ替えて得られる文字列 X を用いて表されます。X の i (1 ≤ i ≤ 26) 文字目は、新たな順番において i 番目に小さい英小文字を表します。 AtCoder 王国には N 人の国民がおり、それぞれの国民の名前は S1​, S2​, …, SN​ です。ここで、Si​ (1 ≤ i ≤ N) は英小文字からなります。 これらの名前を、高橋君の定めたアルファベット順に基づく辞書順に従って並べ替えてください。 辞書順とは? 辞書順とは簡単に説明すると「単語が辞書に載っている順番」を意味します。より厳密な説明として、英小文字からなる相異なる文字列 S, T の大小を判定するアルゴリズムを以下に説明します。 以下では「 S の i 文字目の文字」を Si​ のように表します。また、 S が T より辞書順で小さい場合は S < T 、大きい場合は S > T と表します。 S, T のうち長さが大きくない方の文字列の長さを L とします。i=1,2,…,L に対して Si​ と Ti​ が一致するか調べます。 Si​ = Ti​ である i が存在する場合、そのような i のうち最小のものを j とします。そして、Sj​ と Tj​ を比較して、Sj​ が Tj​ よりアルファベット順で小さい場合は S < T 、そうでない場合は S > T と決定して、アルゴリズムを終了します。 Si​ = Ti​ である i が存在しない場合、S と T の長さを比較して、S が T より短い場合は S < T 、長い場合は S > T と決定して、アルゴリズムを終了します。 以上题目请用c++
03-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值