You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于条件合并多版本相似列表并生成精简代码?

合并多版本列表生成精简代码结构

我有一个根据条件返回多个相似列表之一的函数,该代码由存储数据的Dictionary<int, List<string>>生成(生成器代码较为简单,故不提供实现)。

原始冗余代码

List<string> GetList(int version)
{
    var list = new List<string>();
    if (version == 1)
    {
        list.Add("A");
        list.Add("B");
        list.Add("C");
        list.Add("D");
        list.Add("E");
    }
    if (version == 2)
    {
        list.Add("A");
        list.Add("B");
        list.Add("B2");
        list.Add("B3");
        list.Add("C");
        list.Add("D");
        list.Add("E");
    }
    if (version == 3)
    {
        list.Add("A");
        list.Add("B");
        list.Add("B2");
        list.Add("B3");
        list.Add("D");
        list.Add("E");
    }
    if (version == 11)
    {
        list.Add("A");
        list.Add("B");
        list.Add("B2");
        list.Add("B3");
        list.Add("C");
        list.Add("D");
        list.Add("E");
    }
    return list;
}

当前代码存在大量重复数据,以上仅为简短示例。我希望生成的代码改为如下精简形式:

目标精简代码

List<string> GetList2(int version)
{
    var list = new List<string>();
    list.Add("A");
    list.Add("B");
    if (version >= 2)
    {
        list.Add("B2");
        list.Add("B3");
    }
    if (version <= 2 || version >= 11)
    {
        list.Add("C");
    }
    list.Add("D");
    list.Add("E");
    return list;
}

因此需要一个算法,能够将源Dictionary<int, List<string>>转换为适合生成上述精简代码的形式。

期望的算法接口

我设想的方法签名如下(注意使用了IEquatable<T>,实际列表成员实现了该接口,示例中使用字符串便于理解):

public class ListMerger
{
    public static List<VersionedChunk<T>> Merge<T>(Dictionary<int, List<T>> input) where T : IEquatable<T>
    {
        throw new NotImplementedException();
    }
}

public record VersionRange(int? MinVersion, int? MaxVersion);

public record VersionedChunk<T>(List<T> Data, List<VersionRange> Versions) where T : IEquatable<T>;

单元测试用例

我已为Merge方法准备了如下单元测试:

[TestClass]
public sealed class Test1
{
    [TestMethod]
    public void WhenNoVersions_ReturnEmptyList()
    {
        Dictionary<int, List<string>> input = [];

        var output = ListMerger.Merge(input);

        Assert.AreEqual(0, output.Count);
    }

    [TestMethod]
    public void WhenSingleVersion_ReturnSingleNonVersionedChunk()
    {
        Dictionary<int, List<string>> input = new() { [1] = ["A", "B", "C"] };

        var output = ListMerger.Merge(input);

        Assert.AreEqual(1, output.Count);
        Assert.AreEqual(3, output[0].Data.Count);
        Assert.IsTrue(output[0].Data.SequenceEqual(["A", "B", "C"]));
        Assert.AreEqual(0, output[0].Versions.Count);
    }

    [TestMethod]
    public void WhenAllVersionsAreSame_ReturnSingleNonVersionedChunk()
    {
        Dictionary<int, List<string>> input = new() 
        { 
            [1] = ["A", "B", "C"],
            [2] = ["A", "B", "C"],
        };

        var output = ListMerger.Merge(input);

        Assert.AreEqual(1, output.Count);
        Assert.AreEqual(3, output[0].Data.Count);
        Assert.IsTrue(output[0].Data.SequenceEqual(["A", "B", "C"]));
        Assert.AreEqual(0, output[0].Versions.Count);
    }

    [TestMethod]
    public void WhenElementIsAdded_ProduceVersionedChunk()
    {
        Dictionary<int, List<string>> input = new() 
        { 
            [1] = ["A", "B", "C"],
            [2] = ["A", "B", "B2", "C"],
        };

        var output = ListMerger.Merge(input);

        Assert.AreEqual(3, output.Count);

        Assert.AreEqual(2, output[0].Data.Count);
        Assert.IsTrue(output[0].Data.SequenceEqual(["A", "B"]));
        Assert.AreEqual(0, output[0].Versions.Count);

        Assert.AreEqual(1, output[1].Data.Count);
        Assert.IsTrue(output[1].Data.SequenceEqual(["B2"]));
        Assert.AreEqual(1, output[1].Versions.Count);
        Assert.AreEqual(2, output[1].Versions[0].MinVersion);
        Assert.IsNull(output[1].Versions[0].MaxVersion);

        Assert.AreEqual(1, output[2].Data.Count);
        Assert.IsTrue(output[2].Data.SequenceEqual(["C"]));
        Assert.AreEqual(0, output[2].Versions.Count);
    }

    [TestMethod]
    public void WhenElementIsRemoved_ProduceVersionedChunk()
    {
        Dictionary<int, List<string>> input = new() 
        { 
            [1] = ["A", "B", "C"],
            [2] = ["A", "C"],
        };

        var output = ListMerger.Merge(input);

        Assert.AreEqual(3, output.Count);

        Assert.AreEqual(1, output[0].Data.Count);
        Assert.IsTrue(output[0].Data.SequenceEqual(["A"]));
        Assert.AreEqual(0, output[0].Versions.Count);

        Assert.AreEqual(1, output[1].Data.Count);
        Assert.IsTrue(output[1].Data.SequenceEqual(["B"]));
        Assert.AreEqual(1, output[1].Versions.Count);
        Assert.IsNull(output[1].Versions[0].MinVersion);
        Assert.AreEqual(1, output[1].Versions[0].MaxVersion);

        Assert.AreEqual(1, output[2].Data.Count);
        Assert.IsTrue(output[2].Data.SequenceEqual(["C"]));
        Assert.AreEqual(0, output[2].Versions.Count);
    }

    [TestMethod]
    public void WhenElementIsRemovedAndAddedAgain_ProduceVersionedChunk()
    {
        Dictionary<int, List<string>> input = new() 
        { 
            [1] = ["A", "B", "C"],
            [2] = ["A", "C"],
            [3] = ["A", "B", "C"],
        };

        var output = ListMerger.Merge(input);

        Assert.AreEqual(3, output.Count);

        Assert.AreEqual(1, output[0].Data.Count);
        Assert.IsTrue(output[0].Data.SequenceEqual(["A"]));
        Assert.AreEqual(0, output[0].Versions.Count);

        Assert.AreEqual(1, output[1].Data.Count);
        Assert.IsTrue(output[1].Data.SequenceEqual(["B"]));
        Assert.AreEqual(2, output[1].Versions.Count);
        Assert.IsNull(output[1].Versions[0].MinVersion);
        Assert.AreEqual(1, output[1].Versions[0].MaxVersion);
        Assert.AreEqual(3, output[1].Versions[1].MinVersion);
        Assert.IsNull(output[1].Versions[1].MaxVersion);

        Assert.AreEqual(1, output[2].Data.Count);
        Assert.IsTrue(output[2].Data.SequenceEqual(["C"]));
        Assert.AreEqual(0, output[2].Versions.Count);
    }

    [TestMethod]
    public void WhenElementIsAddedAndRemovedAgain_ProduceVersionedChunk()
    {
        Dictionary<int, List<string>> input = new() 
        { 
            [1] = ["A", "B"],
            [2] = ["A", "B", "C"],
            [3] = ["A", "B"],
        };

        var output = ListMerger.Merge(input);

        Assert.AreEqual(2, output.Count);

        Assert.AreEqual(2, output[0].Data.Count);
        Assert.IsTrue(output[0].Data.SequenceEqual(["A", "B"]));
        Assert.AreEqual(0, output[0].Versions.Count);

        Assert.AreEqual(1, output[1].Data.Count);
        Assert.IsTrue(output[1].Data.SequenceEqual(["C"]));
        Assert.AreEqual(1, output[1].Versions.Count);
        Assert.AreEqual(2, output[1].Versions[0].MinVersion);
        Assert.AreEqual(2, output[1].Versions[0].MaxVersion);
    }

    [TestMethod]
    public void WhenElementsAreAddedAndRemoved_ProduceVersionedChunks()
    {
        Dictionary<int, List<string>> input = new() 
        { 
            [1] = ["A", "B", "C", "D", "E"],
            [2] = ["A", "B", "B2", "B3", "C", "D", "E"],
            [3] = ["A", "B", "B2", "B3", "D", "E"],
            [11] = ["A", "B", "B2", "B3", "C", "D", "E"],
        };

        var output = ListMerger.Merge(input);

        Assert.AreEqual(4, output.Count);

        Assert.AreEqual(2, output[0].Data.Count);
        Assert.IsTrue(output[0].Data.SequenceEqual(["A", "B"]));
        Assert.AreEqual(0, output[0].Versions.Count);

        Assert.AreEqual(2, output[1].Data.Count);
        Assert.IsTrue(output[1].Data.SequenceEqual(["B2", "B3"]));
        Assert.AreEqual(1, output[1].Versions.Count);
        Assert.AreEqual(2, output[1].Versions[0].MinVersion);
        Assert.IsNull(output[1].Versions[0].MaxVersion);

        Assert.AreEqual(1, output[2].Data.Count);
        Assert.IsTrue(output[2].Data.SequenceEqual(["C"]));
        Assert.AreEqual(2, output[2].Versions.Count);
        Assert.IsNull(output[2].Versions[0].MinVersion);
        Assert.AreEqual(2, output[2].Versions[0].MaxVersion);
        Assert.AreEqual(11, output[2].Versions[1].MinVersion);
        Assert.IsNull(output[2].Versions[1].MaxVersion);

        Assert.AreEqual(2, output[3].Data.Count);
        Assert.IsTrue(output[3].Data.SequenceEqual(["D", "E"]));
        Assert.AreEqual(0, output[3].Versions.Count);
    }
}

内容的提问来源于stack exchange,提问作者Dark Daskin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 23:15:53