2016-07-05 13 views
0

Wie finden Sie ein Element in der List-Klasse ohne Schleifen?So finden Sie ein Listenelement mit einer Klasse ohne Schleifeneinheit C#

für gewöhnliches Beispiel nachschlagen Looping mit:

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() { 

    } 
} 

Gibt es eine Idee, einen Artikel zu finden, ohne wie oben solches Looping? Da das Verwenden von Schleifen zum Ermitteln der Elementdaten mehr Speicherplatz erfordert, müssen Sie dies tun. Wenn es mehr als 100 Elemente gibt, wird es verzögert und braucht mehr Zeit.

Dank

+1

wenn das Element gefunden, dann können Sie die Schleife verlassen. auf die eine oder andere Weise müssen Sie den Gegenstand durchlaufen. LINQ kann die Schleife ausblenden, verwendet jedoch immer noch eine Eins. – lordkain

+0

Welcher Typ ist Player.items? – Mfusiki

+0

Wenn die Namen eindeutig sind, können Sie inventoryx.Player.items.ToDictionary (p => p.itemName); Dann können Sie auf inventoryx.Player.items ["Wood"] zugreifen –

Antwort

2

LINQ Verwenden Sie

using Sytem.Linq; 
... 

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

schreiben oder, Um den Index zu finden:

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

Gibt den Index des ersten Elements zurück, der der Bedingung entspricht, oder -1, um anzuzeigen, dass keine Übereinstimmungen gefunden wurden.

Dies ist immer noch O (n), genau wie Ihre Schleife, aber es ist ein bisschen knapper und lesbarer.

auch C# eine foreach Anweisung zur Iteration durch IEnumerable Sammlungen bietet, hilft dies zu verhindern off-by-one Ausnahmen:

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

Wie sieht es aus, wenn der Name der Elemente gefunden wird, wird der Index der Listenelemente mit LINQ zurückgegeben? –

+0

Sie können 'int index = items.FindIndex (i => i.ItemName ==" Wood ");' verwenden, dies liefert entweder den ersten Index oder -1, wenn die Bedingung nicht erfüllt werden kann. –

+0

Ja, das ist absolut was ich will. Danke James Jenkinson. –

3

diese effizienter für viele Elemente Damit Sie ein Wörterbuch zu schaffen betrachten können, Mapping itemName s Artikel:

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

Dann können Sie die Elemente nach Namen zugreifen:

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

Natürlich können Sie das nur tun, wenn die itemName s eindeutig sind. Und du solltest dieses Wörterbuch wahrscheinlich pro Spieler speichern, vielleicht als Eigentum des Spielers, damit du es nicht jedes Mal neu erstellen musst, wenn du einen Gegenstand nachschlagen willst.


Wenn die itemName s nicht eindeutig zuzuordnen sind, sollten Sie könnten eine Wörterbuch-Mapping machen itemName auf eine Liste der Objekte:

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

Wie sieht es aus, wenn in List-Element der selbe itemName ist? –

+0

Dann wird dieser Ansatz nicht funktionieren, weil die Schlüssel im Wörterbuch eindeutig sein müssen.Für Ihren Zweck (um herauszufinden, ob es _ mindestens ein_ Element mit diesem Namen gibt), könnte dies funktionieren, wenn Sie nur ein Element mit diesem Namen hinzufügen. Aber Sie können dies nicht mit 'ToDictionary' machen, sondern müßten das Wörterbuch manuell erstellen. –