【问题标题】:How to combine elements of list? (C#)如何组合列表的元素? (C#)
【发布时间】:2019-05-17 06:13:38
【问题描述】:

我正在使用 C#。

如何在两个列表中组合(求和、加、减)这些类元素?

  class Attribute
  {
     public AttributeType WhatAttri;
     public float amount;
  }

  enum AttributeType{
        maxhp, str, dex, int, wis,,,,
  }

  Attribute[] attList1;
  Attribute[] attList2; 

如果具体数值是这样的,

attList1[0] = new Attribute(AttributeType.maxhp, 6)
attList1[1] = new Attribute(AttributeType.str, 4)
attList1[2] = new Attribute(AttributeType.dex, 3)

attList2[0] = new Attribute(AttributeType.str, 9)
attList2[1] = new Attribute(AttributeType.int, 7)
attList2[2] = new Attribute(AttributeType.wis, 5)

我想要这样的最终结果,(添加attList1 值,减去attList2 值,以及求和(或减或加)重复的AttributeType)

所以在上面两个列表中,AttributeType.str 是相同的,所以从attList1[1]的值(4)中减去重复的attList2[0]的数量变量的值(9) 并从 attList2 中排除该元素。

所以最终的结果应该是,

Attribute[] combinedList; (or List<Attribute> combinedList )

combinedList[0] = new Attribute(AttributeType.maxhp, 6)
combinedList[1] = new Attribute(AttributeType.str, -5)  (4 - 9)
combinedList[2] = new Attribute(AttributeType.dex, 3)
combinedList[3] = new Attribute(AttributeType.int, -7)
combinedList[4] = new Attribute(AttributeType.wis, -5)

如何做到这一点?

谢谢。

【问题讨论】:

  • 到目前为止你尝试了什么?
  • 分组,总和?有人上当了。
  • 我不知道。只是在谷歌上搜索 concat、join、zip,但还不知道。
  • 取Lsource,添加LUpdateState。您现在将拥有一个带有“重复”AttributeType 的列表。 GroupBy 在 AttributeType 上。使用 AttributeType = group.key 选择新属性。和值 = sum(group.amount)

标签: c# arrays list


【解决方案1】:
var result =
     attList2.Select(a => new Attribute(a.WhatAttri, -a.amount)) // line 1
     .Concat(attList1)  // line 2
     .GroupBy(a => a.WhatAttri)  // line 3
     .Select(g => new Attribute(g.Key, g.Sum(a => a.amount)));  // line4

  foreach(var a in result)
  {
    Console.WriteLine($"{a.WhatAttri}: {a.amount}");
  }

您想将第一个列表的计数相加并减去第二个列表的数量。所以首先我将第二个列表转换为一个带有负数的新列表(第 1 行)。然后将两个列表合并为一个列表(第 2 行)。 然后大线按类型分组(第 3 行)。然后你有一个 Key 和 items 的结构,你可以在其中使用 key 和数量的总和创建新的属性(第 4 行)。

编辑:将第 2 行中的“Union”替换为“Concat”以避免删除重复值,以防万一在类 Attribute 中存在自定义比较器方法

【讨论】:

  • 联合删除重复项。这里不是这样,因为GetHashCodeEquals 没有实现,但是如果它们是或者类之间的任何继承。如果它们的总和为 0,您将失去属性。
【解决方案2】:

主要问题是您在属性修饰符中没有正值或负值。你如何提升这些属性?一旦解决了,解决方案就很容易了

使用 concat、GroupBy AttributeType 添加两个列表,然后选择值。

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

public class Program
{
    public static void Main()
    {            
        var attributes = new Attribute[] {
            new Attribute{WhatAttri=AttributeType.maxhp, amount=6 },
            new Attribute{WhatAttri=AttributeType.str, amount=4 },
            new Attribute{WhatAttri=AttributeType.dex, amount=3 },
        };

        //Attribute modifier has to be either positive or negative
        var attributesModifier = new Attribute[] {
            new Attribute{WhatAttri=AttributeType.str, amount=-9 },
            new Attribute{WhatAttri=AttributeType.@int, amount=-7 },
            new Attribute{WhatAttri=AttributeType.wis, amount=-5 },
        };


        var newAttributes = attributes
                                .Concat(attributesModifier)
                                .GroupBy(x => x.WhatAttri)
                                .Select(group => 
                                        new Attribute { 
                                            WhatAttri = group.Key, 
                                            amount = group.Sum(g => g.amount) 
                                        });


        newAttributes.Dump();
    }

    public class Attribute
    {
        public AttributeType WhatAttri { get; set; }
        public float amount { get; set; }
    }

    public enum AttributeType
    {
        maxhp, str, dex, @int, wis
    }
}

在线演示https://dotnetfiddle.net/3C7n7F

【讨论】:

  • 谢谢。但这是我正在制作的一些 RPG 游戏的代码部分。所以通常属性的数量是正值,而不是负值。但在特定情况下,我只需要扣除值来比较两个设备的金额值。
  • 你的意思是你总是会降低统计数据而不是提高他们?你真的希望 5 是减号而 -5 是加号吗?
  • 基本上装备应该提升属性,所以应该是正值。
  • 这里有一个真正的小姐理解。我告诉你:使用 List1 和 List2 没有办法知道你是否必须在不寻找上下文的情况下添加或减去。 “这件事是 5,但消极还是积极?这取决于。”
  • 尝试编写这样的代码:“这是一个双刃恶意,它给出了一个 Str +5 但有一个 -10 Intel。”你必须写 {10 , - 5}。在编码中,一旦没有从您的代码直接翻译成英语,单词的意思就相反了。这是一个很好的迹象,表明您有问题。
【解决方案3】:
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;

public enum AttributeType
{
    maxhp, str, dex, intel, wis,
}

[System.Serializable]
public class Attribute
{
    public AttributeType WhatAttri;
    public float amount;
    public Attribute(AttributeType type, int a)
    {
        WhatAttri = type;
        amount = a;
    }
}

public class LinqTest : MonoBehaviour
{
    Attribute[] attList1 = new Attribute[3];
    Attribute[] attList2 = new Attribute[3]; 
    void Start()
    {
        attList1[0] = new Attribute(AttributeType.maxhp, 6);
        attList1[1] = new Attribute(AttributeType.str, 4);
        attList1[2] = new Attribute(AttributeType.dex, 3);

        attList2[0] = new Attribute(AttributeType.str, 9);
        attList2[1] = new Attribute(AttributeType.intel, 7);
        attList2[2] = new Attribute(AttributeType.wis, 5);

        Calcul();
    }

    void Calcul()
    {
        var result = attList2
                       .Select(a => new Attribute(a.WhatAttri, -(int)a.amount)) // line 1
                       .Union(attList1)  // line 2
                       .GroupBy(a => a.WhatAttri)  // line 3
                       .Select(g => new Attribute(g.Key, g.Sum(a => (int)a.amount)));  // line4

        foreach (var a in result)
        {
            Debug.Log($"{a.WhatAttri}: {a.amount}");
        }
    } 
}

这是通过答案测试上述代码的最终结果。 使用 Unity 引擎。

【讨论】:

    猜你喜欢
    • 2011-01-25
    • 1970-01-01
    • 2021-10-31
    • 2016-12-19
    • 1970-01-01
    • 2020-07-19
    • 2020-05-22
    • 1970-01-01
    • 2019-04-21
    相关资源
    最近更新 更多