M1ke_SK 230 Posted July 28, 2019 I am trying to iterate array elements and remove added items. At the end, I am expecting array of NOT added items to unit. When I add item to player, I remove it from array, but in next iteration I skip to next element. Problem: array have 2x "Titan_AT" so array does not have unique keys. _items = ["Titan_AT","Titan_AT","Titan_AA","NLAW_F","RPG7_F","RPG32_HE_F","RPG32_F"]; { systemChat format ["_item: %1 | _items: %2", _x, _items]; if (player canAdd _x) then { player addItem _x; //remove item from _items; //_items = _items - [_x]; //this will delete both "Titan_AT" from array at 1 iteration _items deleteAt _forEachIndex; // this will skip next element on new iteration }; } forEach _items; systemChat format ["not added items: %1", _items]; EDIT: I used second array _items = ["Titan_AT","Titan_AT","Titan_AA","NLAW_F","RPG7_F","RPG32_HE_F","RPG32_F"]; _left = []; { if (player canAdd _x) then { player addItem _x; } else { _left pushBack _x; }; diag_log format [" _item: %1 | _items: %2 | _left: %3", _x, _items, _left]; } forEach _items; systemChat format ["not added items: %1", _left]; Share this post Link to post Share on other sites
ZaellixA 383 Posted July 28, 2019 Hey there M1ke_SK, one way I could think you can do it is to set the items you remove to a predetermined value and then run another loop that will delete them (after you have iterated once through the array to add items to your unit). This could look like this (quoting your code) private _items = ["Titan_AT", "Titan_AT", "Titan_AA", "NLAW_F", "RPG7_F", "RPG32_HE_F", "RPG32_F"]; { systemChat format["_item: %1 | _items: %2", _x, _items]; if(player canAdd _x) then { player addItem _x; _items set[_forEachIndex, -1]; // Set the value equal to -1 }; } forEach _items; // Loop again through the array to delete the items you removed private _index = 0; // Initialize an index while{_index < (count _items)} do { // Check if the item at the index position is -1 if((_items select _index) isEqualTo -1) then { _items deleteAt _index; // If it is... delete it and do NOT increment the index } else { _index = _index + 1; // Otherwise just go to the next position }; }; systemChat str _items; I have only tested this in Single Player and worked OK. I did not test extensively but it worked just fine for all the tests I ran. In general the "trick" here is to NOT increment the index when you delete (because the next element will move down to your current position). So, no matter what way you will choose, one way will be to take care of the index increments. Please let us know if this works for you or if you require something different. 1 Share this post Link to post Share on other sites
engima 327 Posted July 28, 2019 (edited) This is how I often do: private _itemsToKeep = []; { if (keep_condition) then { _itemsToKeep pushBack _x; }; } foreach _items; _items = _itemsToKeep; But ZaellixA’s solution also seems like a good one. Except I’d do the delete phase in the first loop and skipped the second. EDIT: Corrected the pseudo style code to more exact SQF code after Dedmen’s comment below. (The ”keep_condition” will still need to be replaced by an actual keep condition.) Edited July 29, 2019 by engima Correction. 1 1 Share this post Link to post Share on other sites
Dedmen 2588 Posted July 29, 2019 20 hours ago, engima said: This is how I often do I'm 100% sure you don't. Because that script doesn't work at all. First the `private` at the top is causing a undefined variable error because that's not how private syntax works. Second you are only keeping one item, the last item in the array actually. Third, your array at the end is a single element, and not an array anymore. On 7/28/2019 at 12:50 PM, M1ke_SK said: I am trying to iterate array elements and remove added items. Sounds like a usecase for https://community.bistudio.com/wiki/select _items = ["Titan_AT","Titan_AT","Titan_AA","NLAW_F","RPG7_F","RPG32_HE_F","RPG32_F"]; _items = _items select { systemChat format ["_item: %1 | _items: %2", _x, _items]; if (player canAdd _x) then { player addItem _x; false //Remove element from array } else { true //Keep element in array }; }; systemChat format ["not added items: %1", _items]; 22 hours ago, ZaellixA said: // Loop again through the array to delete the items you removed ughh yuck.. How about _items = _items - [-1] Removes every element that's "-1". Sounds simpler than your very complex looking while loop. 3 1 Share this post Link to post Share on other sites
engima 327 Posted July 29, 2019 I’d say that ZaellixA’s second while is the one to choose if you for some reason do not want the _items variable to reference a new array. I.e. using the deleteAt command. 2 1 Share this post Link to post Share on other sites