【问题标题】:Map value to item from list and add the new value to the same list C#将值映射到列表中的项目并将新值添加到同一列表 C#
【发布时间】:2016-02-03 06:20:31
【问题描述】:

我有一个颜色数组,即。

var colorPallete = new string[]{color1, color2, color3, color4, color5};

我还有一个包含 ID 的对象列表。 例如。 var previousList<MyModel> = new List<MyModel>();

MyModel.cs

public class MyModel()
{
   public int ID {get; set;}
public string Class{get; set;}
public string Name {get; set;}
public string Color {get; set;}
}

我想为具有相同 ID 的对象分配某种颜色。然后将分配的颜色作为新值添加到列表中。

例如:

上一个列表:-

            ID :1
            Name: abc
            Class: Senior

           ID :2
            Name: xyz
            Class: Medium

            ID :3
            Name: pqr
            Class: junior

           ID :1
            Name: mno
            Class: junior

新列表:-

            ID :1
            Name: abc
            Class: Senior
            Color :color1

            ID :2
            Name: xyz
            Class: Medium
            Color :color2

            ID :3
            Name: pqr
            Class: junior
            Color :color3

            ID :1
            Name: mno
            Class: junior
            Color :color1

【问题讨论】:

    标签: c# list dictionary


    【解决方案1】:

    这对我有用:

    var colorPallete = new string[]
    {
        "color1", "color2", "color3", "color4", "color5",
    };
    
    var previousList = new []
    {
        new { ID = 1, Name = "abc", Class = "Senior", },
        new { ID = 2, Name = "xyz", Class = "Medium", },
        new { ID = 3, Name = "pqr", Class = "junior", },
        new { ID = 1, Name = "mno", Class = "junior", },
    };
    
    var newList =
        previousList
            .Select(x => new
            {
                x.ID,
                x.Name,
                x.Class,
                Color = colorPallete.ElementAtOrDefault(x.ID - 1),
            })
            .ToList();
    

    我得到这个结果:


    通过提供MyModel 类的问题更新,代码可以这样编写:

    var colorPallete = new string[]
    {
        "color1", "color2", "color3", "color4", "color5",
    };
    
    var previousList = new List<MyModel>()
    {
        new MyModel() { ID = 1, Name = "abc", Class = "Senior", },
        new MyModel() { ID = 2, Name = "xyz", Class = "Medium", },
        new MyModel() { ID = 3, Name = "pqr", Class = "junior", },
        new MyModel() { ID = 1, Name = "mno", Class = "junior", },
    };
    
    var newList =
        previousList
            .Select(x => new MyModel()
            {
                ID = x.ID,
                Name = x.Name,
                Class = x.Class,
                Color = colorPallete.ElementAtOrDefault(x.ID - 1),
            })
            .ToList();
    

    这给出了:

    现在,这种方法会生成一个新列表,保持旧列表和旧对象不变。一般来说,这是你应该尝试做的。最好仅在您知道对象的设计目的时才对对象进行变异。

    因此可以像这样对原始列表进行就地更新:

    previousList.ForEach(x => x.Color = colorPallete.ElementAtOrDefault(x.ID - 1));
    

    这会导致修改previousList 对象而不创建newList

    【讨论】:

    • 这给了我一个错误Cannot implicitly convert type '.List&lt;AnonymousType#1&gt;' to '.List&lt;mymodel&gt;'
    • @helloworld - 这是意料之中的。当您发布您的问题时,您需要提供所有使用的对象模型。你适应起来应该不会太难,但如果你在问题中发布你的类定义,我很乐意更新我的答案。您可以同时发布previousListnewList 的两种类型吗?
    • 我已经编辑了我的问题。 previousList 和 newList 应该是 List 类型
    • @helloworld - 您不能对添加字段的两个列表使用相同的类型。 Color 如何适应?
    • 请查看我编辑的问题。我在 MyModel 类中添加了另一个属性。会有帮助吗?
    【解决方案2】:

    如果您使用List&lt;T&gt;(不是IEnumerable&lt;T&gt;)并且不想创建新列表,而是需要更新现有列表中的值,则可以使用单个查询来完成。有三种方法可以处理您的场景(A、B、C):

    var colorPallete = new string[]
    {
        "Red", "Green", "Blue"
    };
    
    var list = new List<MyModel>()
    {
        new MyModel() { ID = 1, Name = "model1", Class = "A", },
            new MyModel() { ID = 1, Name = "model11", Class = "AA", },
            new MyModel() { ID = 2, Name = "model2", Class = "B", },
            new MyModel() { ID = 3, Name = "model3", Class = "C", },                            
            new MyModel() { ID = 4, Name = "model4", Class = "D", },
            new MyModel() { ID = 5, Name = "model5", Class = "E", },            
    };
    
    //A. This code assigns null for unknown IDs
    //I.e. if (ID > 0 && ID < colorPallete.Length) then color will be picked from colorPallete[],
    //else it will be null
    list.ForEach(x => x.Color = colorPallete.ElementAtOrDefault(x.ID - 1));
    
    //B. This code apply some default color for unknown IDs
    //I.e. if (ID > 0 && ID < colorPallete.Length) then color will be picked from colorPallete,
    //else it will be "DefaultColor"
    list.ForEach(x => x.Color = colorPallete.ElementAtOrDefault(x.ID - 1) ?? "DefaultColor");
    
    //C. This code can assign the same color to models with different IDs, 
    //but models with identical IDs always will have identical color
    list.ForEach(x => x.Color = colorPallete.ElementAtOrDefault((x.ID - 1) % colorPallete.Length));
    

    【讨论】:

    • 嗨,我尝试了这种方法,但我得到的颜色为空。另外,我有一个固定的颜色数组,因为列表中的 ID 可以超过颜色的数量
    • @helloworld 嗨,我已经更新了我的答案以满足您的要求。有三种方法可以处理您的场景。可能我还是误会了什么。如果是这样,请随时通知我。你可以玩我的代码here
    • 感谢您在 Fiddle 上的示例。帮我拍了一张更好的照片。第三种方法正是我想要的。接受你的回答。祝你有美好的一天
    【解决方案3】:

    我会为具有如下颜色属性的对象创建一个类:

    public class MyClass
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Class { get; set; }
        public string Color { get; set; } // Nullable
    }
    

    对于颜色,我会创建另一个带有 ID 的类来与MyClass 的 ID 进行比较:

    public class MyColor
    {
        public int ID { get; set; }
        public string Color { get; set; }
    }
    

    对于 colorPalette 中的每种颜色,您将分配一个与 MyClass 列表的 ID 匹配的 ID。

    所以一开始 MyClass 的颜色是空的。然后你可以遍历MyClass的列表:

    foreach (MyClass myClass in myClassList)
    {
        myClass.Color = colorPalette.FirstOrDefault(col => col.ID = myClass.ID);
    }
    

    或者在 Color 类中没有 ID(比较变量的名称,这不是一个很好的解决方案):

    foreach (MyClass myClass in myClassList)
    {
        myClass.Color = colorPalette.FirstOrDefault(col => int.Parse(nameof(col.Color).Replace("color", "")) == myClass.ID);
    }
    

    【讨论】:

    • 感谢您的回复。这里的颜色是什么?
    • 编辑了我的答案。 colors 应该是 colorPalette,对此感到抱歉。
    • 谢谢。我仍然无法得到 col.ID 。我想我错过了一些东西。您能否发布我如何获得 col.ID。
    • 在答案中添加了 MyColor 类。
    • 嗯,我的颜色是字符串。那么应该有字符串而不是颜色吗?请原谅我是 C# 新手
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-09
    • 1970-01-01
    • 2013-05-30
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多