【问题标题】:C# - How to get item from Generic List with the highest specific parameter?C# - 如何从具有最高特定参数的通用列表中获取项目?
【发布时间】:2016-08-13 21:33:20
【问题描述】:

我已经搜索了很多,但找不到我理解到足以翻译到我的项目中的答案。目标是什么:我需要在列表中找到一个具有最高 armour_class 参数的物品,并将该物品的 armour_class 添加到角色的盔甲等级中。

所以,我们以这种方式创建了一个列表:

public List<Weapon> characterInvWeapon;
public List<Armor> characterInvArmor;

等等

以下是 Armor 类及其属性的创建方式:

public class Armor : Item, IComparable <Armor> {
  public string armor_prof;
  public string armor_category;
  public int armor_class;
  public int armor_str_req;
  public string armor_stealth_mod;

  public Armor (string c_name
      , string c_description
      , bool c_stackable
      , int c_value
      , string c_coin_type
      , int c_weight
      , string c_armor_prof
      , string c_armor_category
      , int c_armor_class
      , int c_armor_str_req   
      , string c_armor_stealth_mod) : base (c_name, c_description, c_stackable, c_value, c_coin_type, c_weight)
  {
      armor_prof = c_armor_prof;
      armor_category = c_armor_category;
      armor_class = c_armor_class;
      armor_str_req = c_armor_str_req;
      armor_stealth_mod = c_armor_stealth_mod;
  }

  public int CompareTo(Armor other)
  {
      if (armor_class == other.armor_class)
        return String.Compare (name, other.name); // a < ab < b 
      else
        return other.armor_class - armor_class;
  }
}

Armor 是一个继承自 Item 类的类,它具有前 6 个属性。 Armors 存储在一个特定于 Armor 的列表中 - public List&lt;Armor&gt; characterInvArmor;

示例项目:

AddToItemStore(new Armor("Breastplate", "Description.", false, 400, "gp", 20, "Breastplate", "Medium Armor", 14, 0, ""));

添加脚本:

public void AddToCharacterInventory(Item it)
    {
        if (it is Weapon)
        {
            charInvWeapon.Add((Weapon)it);
            charInvWeapon.Sort();
        }
        else if (it is Armor)
        {
            charInvArmor.Add((Armor)it);
            charInvArmor.Sort();
        }
    }

现在正如我所提到的,我需要在列表 charInvArmor 中找到一个具有最高 armour_class 参数的项目,并在其他函数中使用它的值,该函数从许多变量中计算装甲等级。

所以在其他函数中,characterArmorClass = armorWithHighestArmorClass + otherVariable + someotherVariable;

我怀疑 Linq 中有一些方便的快捷方式,但我会非常感谢没有 Linq 的一些示例。 Linq 也会受到欢迎,但我对它完全陌生,例如,我担心性能和我的应用程序与 iPhone 的兼容性。我读过 iOS 会导致 Linq 出现问题。这必须是快速且兼容的计算。

【问题讨论】:

    标签: c# sorting unity3d unity5 generic-list


    【解决方案1】:

    使用 LINQ:

    int maxArmorClass = characterInvArmor.Max(armor => armor.armor_class);
    

    没有带排序的 LINQ:

    var list = characterInvArmor.ToList(); // copy list, so we do not break sorted orded
    list.Sort((armor1, armor2) => armor2.armor_class.CompareTo(armor1.armor_class));
    int maxArmorClass = list[0].armor_class;
    

    当然,您也可以随时编写带有循环和“max”变量的手动方法。

    顺便说一句,我注意到,您在 AddToCharacterInventory 方法中对 charInvArmor 进行排序。如果始终对数组进行排序,那么根据您的CompareTo 实现,具有最大armor_class 的项目应该总是最后一个(或者第一个,我不确定)。因此,只需获取列表的最后一个(第一个)元素。

    【讨论】:

    • 谢谢,似乎比我想出的要好。是的,它在这里排序,但有时我添加项目而不对它们进行排序,并且很好奇是否有其他方式。是的,也许我不希望稍后以这种方式排序列表 - 我认为每次对其进行排序并按其他参数再次排序会降低性能成本,而且对于这种“简单”任务来说操作太大。因此,复制列表的解决方案已经是一个更好的主意了。
    【解决方案2】:

    您必须遍历列表并检查每个值,因为列表不是根据 Armor 类值排序的,而且您不想使用 LINQ:

    int maxArmorClass = 0;
    foreach (var armor in characterInvArmor)
    {
        // Do a comparison here and see if you found a higher value
        // If a higher value is found, store it in maxArmorClass
    }
    

    作为旁注,我推荐以下链接:

    Public Fields versus Automatic Properties

    Style guide for c# * 在 C# 中,Pascal 大小写和 Camel 大小写是既定的约定。

    【讨论】:

    • 是的,这可能是最好的方法。但是在这种情况下,如果它们都是“盔甲”,我该如何比较它们呢?附言。我会读的,谢谢,我对 C# 和编码真的很陌生,所以我在这一点上犯了很多错误。
    • @Sarr:你不能简单地做if (armor.armor_class &gt; maxArmorClass)吗?我不确定您所说的 if they are all "armor" 是什么意思。
    • 哦,该死的,对不起,没想到明显的事情。退房。 // 这就是它,对我来说绝对是绝妙和最简单的解决方案。谢谢,它将在许多其他领域有所帮助。
    猜你喜欢
    • 2011-11-02
    • 2019-12-18
    • 2011-11-22
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多