c# - Order of operations in a foreach loop -



c# - Order of operations in a foreach loop -

i changed way crafting table works , i've run problem. way works displays item in crafting list. if can't create item, item texture in table translucent.

my problem when checking if item can crafted, setting bool variable cancraft true or false , not setting correctly.

public void checkforavailablecrafts(player player) { foreach (itemrecipe recipe in craftinglist) { if (recipe.checkforitemsneeded(player) != null) { output = recipe.output; updatetable(output); } else if (recipe.checkforitemsneeded(player) == null) { output = new item(); output.itemname = "empty"; updatetable(output); }

the checkforitemsneeded method works correctly because worked fine before rewrote part of code. if have amount of items recipe cancraft item true. problem lies within updatetable method.

private void updatetable(item output) { foreach (item item in craftingtableitems) { if (output.itemname == item.itemname) { item.cancraft = true; if (output.itemname == "empty") { item.cancraft = false; } } } }

my craftingtableitems list of 12 items, , each item set recipe in craftinglist. have 6 items in craftingtable aren't empty.

after i've crafted item, item in table should homecoming false value, doesn't. order of operations in loop correct?

i suspect problem output variable. it's not defined part of method, , hence modified other code thread. alter code create variable local method (general rule of thumb: utilize smallest scope possible variable) or eliminate entirely, i'd re-write whole thing this:

public void checkforavailablecrafts(player player) { //names of items player can craft var names = craftinglist.where(r => r.checkforitemsneeded(player) != null) .select(r => r.output.itemname); //item objects player can craft var items = craftingtableitems.join(names, => i.itemname, n => n, (i, n) => i); //set false (base state) foreach (var item in craftingtableitems) {item.cancraft = false;} //set items player can craft true foreach(var item in items) {item.cancraft = true;} }

not less code, should much more efficient, prior code had check every craftinglist entry every possible item player craft... o(n2), while (i think) o(n log n), maybe close o(n).

yes, .join() phone call looks greek if you're not used lambda expressions, it's not hard, , again: simplifies , speeds code. can simplify farther if have equalitycomparer class compares 2 items based on name, or if item type implements iequatable compare on itemnames (and may find useful anyway). assuming latter, item correctly implements iequatable, code this:

public void checkforavailablecrafts(player player) { //items player can craft var craftableitems = craftinglist.where(r => r.checkforitemsneeded(player) != null) .select(r => r.output); //items objects craftingtable player can craft craftableitems = craftingtableitems.intersect(craftableitems); //set false (base state) foreach (var item in craftingtableitems) {item.cancraft = false;} //set items player can craft true foreach(var item in craftableitems) {item.cancraft = true;} }

if can't spot difference @ first, first statement saves step in select projection, , sec statement changes ugly join() function easier-to-read intersect()

c# loops foreach

Comments

Popular posts from this blog

formatting - SAS SQL Datepart function returning odd values -

c++ - Apple Mach-O Linker Error(Duplicate Symbols For Architecture armv7) -

php - Yii 2: Unable to find a class into the extension 'yii2-admin' -