如何在不循环 unity c# 的情况下使用 class 查找列表元素

How to find List element with class without looping unity c#

如何在不循环的情况下查找列表 class 中的元素?

例如使用循环的普通查找:

for(int i = 0; i < inventoryx.Player.items.Count; i++) {
            if(inventoryx.Player.items[i].itemName == "Wood") {
                Debug.log("You Find The Wood");
            }
            else {
                Debug.Log("Can't Find The Wood");
            }
        }

items.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

// Make Class Item

public class item {
    public string itemName;
    public int itemID;
    public string itemDesc;
    public string itemIcon;
    public GameObject itemModel;
    public int itemTime;
    public int hightprice;
    public int stdprice;
    public int itemStock;
    public int harvest;
    public RawTree rawTree;
    public ItemType itemType;
    public ItemProd itemProd;
    public ItemLocation itemLocation;
    public int Lvlunlock;
    private string baseName;
    public int itemExp;

    public enum ItemType {
        Raw,
        Admirable,
        Valuable
    }

    public enum RawTree {
        BigTree,
        SmallTree,
        Field,
        None
    }

    public enum ItemProd {
        Corps,
        Dairy,
        JuiceJamMaker,
        Kitchen,
        Bakery,
        CraftHouse,
        ChickenCoop,
        FishingSpotMountain,
        CowPasture,
        LunaMine,
        PigPen,
        FishingSpotLake,
        TropicalWood,
        SheepPasture,
        FishingSpotSea,
        Beebox,
        HomeIndustry
    }

    public enum ItemLocation { 
        Home,
        Orchard
    }

    public item (string name, int ID, string desc, int harvestx, int time, int stdpricex, int hightpricex, int stock, int Lvlunlockx, RawTree RawTree, ItemType type, ItemProd prod, string folderx, ItemLocation location, int Exp) {
        itemName = name;
        itemID = ID;
        itemDesc = desc;
        harvest = harvestx;
        itemTime = time;
        stdprice = stdpricex;
        hightprice = hightpricex;
        itemStock = stock;
        Lvlunlock = Lvlunlockx;
        rawTree = RawTree;
        itemType = type;
        itemProd = prod;
        itemIcon = folderx;
        itemLocation = location;
        itemExp = Exp;
    }

    public item() {

    }
}

有没有像上面这样不用循环查找项目的想法? 因为使用循环查找元素数据会占用更多内存。如果有超过 100 个项目,它将导致延迟并花费更多时间。

谢谢

为了使许多项目更有效,您可以考虑创建字典,将 itemNames 映射到项目:

Dictionary<string, Item> itemNamesToItem = inventoryx.Player.items.ToDictionary(i => i.itemName, i => i);

然后您可以按名称访问项目:

if (itemNamesToItem.ContainsKey("Wood"))
    Debug.log("You Find The Wood");
else
    Debug.Log("Can't Find The Wood"); 

当然,只有 itemName 是唯一的才能这样做。你可能应该为每个玩家存储这个字典,也许作为玩家的 属性,这样你就不必每次要查找项目时都重新创建它。


如果 itemName 不是唯一的,您可以考虑制作字典映射 itemName 到项目列表:

Dictionary<string, List<Item>> itemNamesToItem =
    inventoryx.Player.items.GroupBy(i => i.itemName)
                  .ToDictionary(g => g.Key, g => g.ToList());

使用 LINQ 你可以编写

using Sytem.Linq;
...

bool hasWood = inventoryx.Player.items.Any(i => i.ItemName == "Wood");

或者,查找索引:

int index = items.FindIndex(i => i.ItemName == "Wood");

其中 returns 匹配条件的第一个项目的索引,或 -1 表示未找到匹配项。

虽然这仍然是 O(n),就像您的循环一样,但它更加简洁和可读。

此外,C# 提供了一个 foreach 语句来遍历 IEnumerable 集合,这有助于防止差一异常:

foreach (var item in inventoryx.Player.items)
{
    if (item.ItemName == "Wood")
        Debug.log("You Find The Wood");
}