Welcome to Keen Software House Forums! Log in or Sign up to interact with the KSH community.
  1. You are currently browsing our forum as a guest. Create your own forum account to access all forum functionality.

group by name List<IMyInventoryItem>

Discussion in 'Programming Questions and Suggestions' started by Archetypal, Jul 13, 2015.

Thread Status:
This last post in this thread was made more than 31 days old.
  1. Archetypal Trainee Engineer

    Messages:
    23
    Hey guys,

    I'm trying to group an item list by the subtypename so i don't have multiple entries of the same item.
    like
    item 0 = stone with amount 50
    item 1 = stone with amount 20
    shoud be
    item 0 = stone with amount 70

    i'm failing to do that and i guess i'm missing something because i don't think it is that hard.
    can someone give me an example of working code?
     
  2. Wicorel Senior Engineer

    Messages:
    1,242
    Are you trying to move the items in inventory?

    If so, BARABAS will do that for you.


    If you want to make a combined list in your script, then I'm not sure what problem you're having.
    Do you have code that's not working? If you want an example, maybe start with Barabas
     
  3. Archetypal Trainee Engineer

    Messages:
    23
    No, i just want to display the ore in all cargo containers and drills on a lcd screen.
    I go through the cargo containers and drills and add the items to a list. But if there is iron in one container and iron in one drill, it will show up twice when I display it on the lcd. So i tried "GroupBy", but it didn't compile. I tried a few solutions i googled, but couldn't make it work.

    Code:
     for (int i = 0; i < cargolist.Count; i++)
                {
                    IMyInventoryOwner invowner = (IMyInventoryOwner)cargolist[i];
                    IMyInventory inv = invowner.GetInventory(0);
                    itemlist.AddList<IMyInventoryItem>(inv.GetItems());
                }
                for(int i = 0; i < drills.Count; i++)
                {
                    IMyInventoryOwner invowner = (IMyInventoryOwner)drills[i];
                    IMyInventory inv = invowner.GetInventory(0);
                    itemlist.AddList<IMyInventoryItem>(inv.GetItems());
                } 
     
  4. d4rky1989 Apprentice Engineer

    Messages:
    332
    This should work. You can adapt the block filtering at line 5 to your liking.
    Code:
    void Main (string argument) {
        var ores = new Dictionary<string, Decimal> ();
    
        GridTerminalSystem.Blocks
            .FindAll (b => b.HasInventory() && b.CubeGrid == Me.CubeGrid)
            .ConvertAll (b => b.GetInventory(0).GetItems())
            .ForEach (items => items
                .FindAll (item => item.Content.TypeId.ToString ().Contains ("Ore"))
                .ForEach (item => {
                    var name = item.Content.SubtypeName;
                    if (ores.ContainsKey (name))
                        ores[name] += (Decimal) item.Amount;
                    else
                        ores.Add (name, (Decimal) item.Amount);
                }
            ));
    
        var e = ores.GetEnumerator ()
        while (e.MoveNext())
            Echo (e.Current.Key + ": " + e.Current.Value);
    }
     
    Last edited: Jul 13, 2015
    • Like Like x 1
  5. Archetypal Trainee Engineer

    Messages:
    23
    thank you very much, i will look into that (since i really want to understand the code i'm using)
    in the meanwhile i managed to make it work with my own solution, but yours seems to be shorter and cleaner.
     
  6. d4rky1989 Apprentice Engineer

    Messages:
    332
    You can use your code and extend it storing the items in a dictionary the way I do it.
     
  7. BumbleGrum Trainee Engineer

    Messages:
    11
    ** This doesn't compile anymore! Can anybody supply an update that will compile?
     
  8. d4rky1989 Apprentice Engineer

    Messages:
    332
    This should work:
    Code:
    List<IMyTerminalBlock> blocks = new List<IMyTerminalBlock>();
    Dictionary<string, Decimal> ores = new Dictionary<string, Decimal>();
    
    public void Main(string argument, UpdateType updateSource)
    {
    	GridTerminalSystem.GetBlocksOfType(blocks, b => b.HasInventory && b.CubeGrid == Me.CubeGrid);
    
    	ores.Clear();
    	blocks.ForEach(block => {
    		var inv = block.GetInventory(0);
    		inv.GetItems().ForEach(item => {
    			var content = item.Content;
    			if (content.TypeId.ToString().Equals("MyObjectBuilder_Ore")) {
    				Decimal amount = 0;
    				ores.TryGetValue(content.SubtypeName, out amount);
    				amount += (Decimal) item.Amount;
    				ores[content.SubtypeName] = amount;
    			}
    		});
    	});
    
    	var e = ores.GetEnumerator();
    	while (e.MoveNext()) {
    		Echo (e.Current.Key + ": " + e.Current.Value);
    	}
    }
    
     
Thread Status:
This last post in this thread was made more than 31 days old.