0
\$\begingroup\$

I'm trying to break up a C# List<InventoryItem> into multiple lists based on two different values: InventoryItem.name and InventoryItem.isStackable.

I want the list to be broken up into multiple lists for the purpose of populating my UI with the data - while keeping non-stackable items in their own list (one item per item slot in UI terms.)

If this is the input:

{
   InventoryItem - name:apple,  stackable:true
   InventoryItem - name:apple,  stackable:true
   InventoryItem - name:carrot, stackable:true
   InventoryItem - name:knife,  stackable:false
   InventoryItem - name:knife,  stackable:false
 }

I should get this output:

{
   InventoryItem - name:apple, stackable:true
   InventoryItem - name:apple, stackable:true
 }
 {
   InventoryItem - name:carrot, stackable:true
 }
 {
   InventoryItem - name:knife, stackable:false
 }
 {
   InventoryItem - name:knife, stackable:false
 }

I'm successfully separating by name alone (see below), but I'm not sure how to take isStackable into account. I'm also using LINQ which I'd prefer to avoid if possible.

var itemsByType     = new List<List<InventoryItem>>();
var inventoryByItem = inventory.GroupBy(x => x.name);
foreach(var v in inventoryByItem)
{
    var itemList = v.ToList();
    itemsByType.Add(itemList);
}
\$\endgroup\$
1
\$\begingroup\$

I think a better aproach would be to store the quantity of an item, instead of storing the stackable itens repeatdly in a list. Because when we are talking about large amounts of stacking items, it wouldn't work;

using UnityEngine;
using System.Collections.Generic;
public class StackExchange : MonoBehaviour
{
    List<InventItem> rawInventory;
    List<InventSlot> groupedInventory;

    void Start () {
        rawInventory = new List<InventItem>();
        rawInventory.Add(new InventItem("apple" , true));
        rawInventory.Add(new InventItem("apple", true));
        rawInventory.Add(new InventItem("carrot", true));
        rawInventory.Add(new InventItem("knife", false));
        rawInventory.Add(new InventItem("knife", false));
        rawInventory.Add(new InventItem("knife", false));

        groupedInventory = new List<InventSlot>();
        foreach (InventItem i in rawInventory){
            proccessItem(i);
        }

        Debug.Log(getPrintableList(rawInventory));
        string s = "Grouped list:\n";
        foreach (InventSlot slot in groupedInventory){
            s += "{\n";
            for (int i = 0; i < slot.quantity; i++)
                s += slot.item.output();
            s += "}\n";
        }
        Debug.Log(s);
    }

    string getPrintableList (List<InventItem> list){
        string output = "{\n";
        foreach (var v in list){
            output += v.output() ;
        }
        output += "}\n";
        return output;
    }


    void proccessItem (InventItem item){
        foreach (var inventSlot in groupedInventory)
            if (inventSlot.item.name == item.name && inventSlot.item.isStackable){
                inventSlot.quantity++;
                return;
            }
        groupedInventory.Add ( new InventSlot (item));
    }

 }

class InventSlot{
    public InventItem item;
    public int quantity;
    public InventSlot (InventItem item){
        this.item = item;
        quantity = 1;
    }
}

class InventItem
{
    public string name;
    public bool isStackable;

    public InventItem (string name , bool isStackable){
        this.name = name;
        this.isStackable = isStackable;
    }

    public string output (){
        return "\tInventoryItem - name:" + name + ", stackable:" + isStackable + "\n";  
    }
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.