Are 64 nested If/Else statements bad? - c#

I've got a bit of a dilemma. I have to do some sorting of a list. There are 2 lists that users can select from and then select one of the elements in that list to sort on. Unfortunately for me, the second list is a child list, within the first list.
The child list will require slightly different logic other than if the user just chose from the parent list. I have the logic down to sort on either the parent and/or the child list using LINQ so I'm not too worried about the logic of it.
There is also the option to choose on ascending or descending order to make matter worse, at least for me. I've gone through the logic and it looks as though there will be a total of 64 if/else statements that I will need to use in order to incorporate all the scenarios.
My first reaction was that this wasn't a very good way to go about it as this seems like a lot of if/else statements. Is there a better way to go about this or do I just need to bite the bullet:
Logic for Parent:
Positions.Select(x => x.Product).OrderBy(x=>x.Price).AsQueryable();
Logic for Child:
Positions.Select(x => x.Product).OrderBy(x=>x.Performance.OrderBy(c=>c.AssortmentCategory).Select(c=>c.AssortmentCategory).FirstOrDefault()).AsQueryable();
Positions and Performance are both ListExtended's, if that matters. Also, I'm using the Dynamic LINQ library as I will be getting user input, though that is not shown above.
Edit1: I forgot to say this sorts only the parent list. Even if they choose an element from the child list, it will sort the parent list.

I would have a lookup dictionary that maps selection from first list (string, int ,? not sure what type you need) to a Func<> and do
var sortedData = sortDict[selected](args....)

Related

Trying to find an approach for an item crafting system for a Unity game

EDIT: I found a solution that works without needing to overhaul much of what I've done... and made myself feel like a fool, because it was at the top of my notes from when I started this project a week ago.
A dictionary containing names and IDs of items will exist, the game will add the ID of any given item to the mixing pot list, sort them in numerical order, and compare the result to a recipe dictionary.
I'll leave the original question here in case anyone else happens to have my weirdly specific problem.
The basic problem I aim to solve is a system in which the player can add ingredients to a mixing pot, click a button, and the game will read the list of ingredients and return a potion (or any other item, but I'm speaking on potions for simplicity's sake). The recipes for potions can get somewhat specific, and potions may need multiple of specific ingredients. The player might also add ingredients in an arbitrary order, and I want to account for that.
My original plan, when I started this project, was for each item to be loaded from a JSON or something, where they'd have a formID based on their list position. This formID would be taken for all the items thrown in the mixing pot, sorted, then checked against a dictionary of all craftable items to find what potion was made.
The problem I've run into, however, is that the detail and scale of my item system has grown to the point where each item is its own programmed object interfacing with a list of traits, each of which is their own programmed object with an interface for determining their parent items' function. For a clearer explanation, the structure I've gone with derives from this post: https://gamedev.stackexchange.com/questions/147873/creating-a-robust-item-system
Constructing things in this way allows for me to have an immense amount of flexibility in what any given item can do, what can be done with it, and what it can interact with. However, I can't be certain of the exact number of components or properties any given item should have, which makes building a JSON a bit complicated. I'm willing to do it, but I'm trying to poke around for options.
The way I see it, I could either restructure my items from the ground up to load from some sort of database file (which I feel would take away from some of the control I have over the unique function, interactivity, and variety of each given item) for the FormID method, or I could do something else.
The only other ideas I've had so far are adding some sort of FormID manually (which seems like a pain to keep track of), or taking the item name strings from the list of items in the pot, sorting them alphabetically, concatenating them together, and doing a dictionary sweep that way, but I feel like that would be far from ideal. I'm somewhat new to this particular aspect, but I'll do what I can to answer questions.
I recommend the database approach.
At first glance I see it consisting of 3 Tables.
Potion table this is where you would store any intrinsic information that all potions share like a Name, you can also store any traits here in one column using JSON.
Ingredients table this is where you would store all possible ingredients.
Potion_Ingredients table this is a relational table that links any number of ingredients to any number of potions.
Example of a potion in the DB.
ID| NAME |TYPE | EFFECT
1 | Regen Potion |Regen | {"HP":"50","RegenPerTick":".5"}
The Name will be used for display purposes.
The Type will be used by the Consumer to determine how to handle the Potion.
The Effect will be used in context with the Type to act in a general way.
Using JSON in this situation would allow you to store any number of effects per potion.
This post is all over the place, to the point that I can't really tell what you're asking about. You start out talking about crafting and items, so I thought it would be about how you check a list of ingredients against a list of recipes, but then you pivot to traits and deserializing from JSON, but then you provide an example of a healing potion and I can't tell why, then you seem to go back to deserializing and finally back to ingredient matching.
I think it would help you a lot to outline what you're trying to do with a sequence diagram or similar and try to break down your approach into manageable parts. The ingredient matching doesn't have anything to do with deserializing, which in turn shouldn't really have much to do with your possible potion types.
In general, I would urge you to respect encapsulation. When you say:
each of which is their own programmed object with an interface for determining their parent items' function.
that's a big screaming red flag to me. Why would a potion know about a sword or a scythe or a maul or a mace or a halberd etc. etc. A potion just knows it gives +5 to attack for 40 seconds. It's up to the user to know how to use it. Using an attack potion on bracers or boots doesn't do anything because they don't implement the IAttack interface, etc., but because it's an item it still implemented the IItem interface which means it can ApplyPotion(). The potion still gets used, it just gets lost (fizzles).
Traits or modifiers, like a fire opal instead of a regular opal, etc., are just bonuses. They should still count as their base ingredients (opal) for the purposes of ingredient checking, but when you make the potion you aggregate the bonuses on all ingredients and apply them to the finished product. You can have it such that multiple bonuses don't stack, or they do, or they do to an extent, or there could be tiers of bonuses like Fire I, Fire II, etc.
For crafting, you could make a string or int be the key in a dictionary, and you can build that key by assigning each ingredient class its own location, so ones indicates the number of feathers, tens is opals, hundreds is scales, thousands is gold, etc., such that a spell of 1201 would be one piece of gold, two scales, and one feather.
Maybe instead of a dictionary that returns subclasses of Potion you could use a switch statement in a PotionFactory that just configures a single base Potion class. If it doesn't find a match the default case could return null and you fail to build, or you could destroy all the ingredients, etc.
Deserializing is relatively straightforward when you use something like XML if you just make each component responsible for deserializing itself. Load the XML file, and when you get to a Potion tag you instantiate a new potion then hand the XML reference to the Potion. The Potion knows what fields it has and which are required and which are optional. Any classes that Potion needs also deserialize themselves, so each time you hit a Bonus tag you'd instantiate a Bonus, add it to the Potion bonuses, and hand the XML reference off to the Bonus to deserialize whatever it needed. This is almost like a recursive function - it goes as deep as it needs to go.
Anyways this is kind a rambling answer to a rambling question, but hopefully it helps point you in some better directions.

Which collection would be appropriate for this task?

I am working with C# and now trying to improve an algorithm (different story there), and to do that I need to have this data structure:
As you can see it is a linked list, where each node can have zero or one "follower"(the right ones). I am still thinking if more than one is necessary.
I could implement these linked lists by myself "raw" but I am thinking it would be much better if I use a collection from the ones available (such as List etc).
So far I am thinking of building a class "PairClass" which will have the a "first element" and a "follower". (the left node and right node). This could change if I decide to include more than one linked nodes(followers). Then using a List<PairClass>
One final consideration is that it would be nice if the data collection permits me to get the follower by giving the first element in an efficient manner.
Due to this last consideration, I am not sure if List<PairClass> would be the best approach.
Can someone advice me on what to use in these cases? I am always open to learn and discuss better ways of doing things. Basically I am asking for an efficient solution to the problem
EDIT: (in response to the comments)
How do you identify each node, is there an ID? or will the index in a list suffice?
So far, I am content with using just simple integers. But I guess you are right, you just give me an idea and perhaps the solution I need is simpler than I thought!
What are your use cases? How often will you be adding or removing elements? Are you going to iterate over this collection?
I will be adding elements often. The "follower" would likely be replaced often too. The elements are not going to be removed. I am going to iterate over this collection in the end, the reason being that followers are going to be eliminated as elements of consideration and replaced by their first element
(Note aside). The reason I am doing this is because I need to modify an algorithm that is taking too much time, This algorithm performs too many scans on an image (which takes time) so I plan to build this structure to solve the problem, therefore speed is a consideration.
You really need to add more details, however by your description
If you don't need to iterate over the list in order
If you have a key for each node
If you want fast lookups
You could use a Dictionary<Key,Node>
Node
public class Node
{
// examples
public string Id {get;set;}
public Node Parent {get;set;}
public Node Child {get;set;}
public Node Sibling {get;set;}
}
Option 1
var nodes = new Dictionary<string,Node>();
// add like this
nodes.Add(node.Id,node);
// look up like this
node = nodes[key];
// access its relatives
node.Parent
node.Child
Node.Sibling
If you want to iterate over the list often
If the index is all you need to look up the node
Or if you want to query the list via Linq
Option 2
var list = new List<Node>;
// lookup via index
var node = list[index];
// lookup via Linq
var node = list.FirstOrDefault(x => x.Id == someId)
In case it is a single follower scenario then I would suggest dictionary of list as a possible candidate as dictionary will make it accessible faster vertically and being a single follower list you can easily use a link list.
In case it is a multiple follower scenario I would suggest dictionary of dictionary collection which will make whole collection faster to access both vertically or horizontally.
Saruman gave a fairly good example of implementation.

How to create a derived list of distinct items using Reactive Extensions?

Let's say I have an IReactiveList<string> named Items from which I'd like to create some derived list DerivedItems (of type IReactiveList<string> or IReactiveDerivedList<string>) of distinct items only.
Items.CreateDerivedCollection(...) has all the bells and whistles I'd like to use, but it doesn't appear to have an option for filtering out duplicates.
I tried Items.Distinct().CreateDerivedCollection(...), but CreateDerivedCollection() no longer tracks changes when used with Distinct().
I tried Items.Changed.Throttle(...).Subscribe(_ => ResetImpl()) where ResetImpl clears DerivedItems and adds each item in Items one-by-one, but then I get exceptions stating that the enumeration cannot complete because the collection was modified. (This occurs primarily when I add dependencies on DerivedList.) I can add a lot of locks but this seems pretty messy.
Finally I tried manually triggering off Items.IsEmptyChanged.Where(b => b) and Items.ItemsAdded in an attempt to manually synchronize Items and DerivedItems, but here I run into a lot of timing issues where list clearing and item addition do not consistently happen in the right order.
I get the feeling I'm missing an easy solution to this problem. How do you do this?
I have a way of doing it, but it's not using IReactiveDerivedList:
var distinctElements = Items.Distinct().ToList();
Items.Changed.Subscribe(y =>
{
distinctElements = Items.Distinct().ToList();
});

.NET: Observable + Sortable CollectionView on a Set (custom HasSet<>)

I look for a way to observe a collection for changes, without using indices. I know when items are added and removed from the source collection, but the collection is not using indices (it's a custom kind of hashset with notification on add/remove). Items are being populated to the list in a undeterministic order and using indices wouldnt make much sense, so I'm trying to avoid it completely. But Im still going to bind this list to a view, so there will be some ordering of the items eventually. My goal is to have all the ordering in a collectionview.
The question is if there is a way to make a collectionview on a index-less source collection and still get the UI to respond to items being removed and added effectively without having to rebuild the list everytime. I'm not sure if I make any sense here. My goal is to get rid of indices but still benefit from collectionchanged-events and collectionview-ordering. Possible?
UPDATE
I've tried to implement a custom ICollectionView such as SetCollectionView(HashSet set) but it won't work for some reason. Not yet anyway.
Another option could perhaps be to implement a custom ReadOnlyObservableCollection-wrapper with some custom ordering on the GetEnumerator. I haven't tested it yet. I would have to sort the list according to the choosen ordering before extracting the index for the NotifyCollectionChanged-event but that should work.
You can use the ObservableHashSet class.
See the question here
How can I make an Observable Hashset in C#?
or go directly to the code here:
http://geoffcox.bellacode.com/2011/12/09/observablehashset/
You need to have an index somewhere, because all of the UI binding plumbing is index-based. You can layer an indexed list over your existing hashset, but it's going to be slow (I can't provide a formal proof, but my gut tells me it would be quite awful, something like O(n)). If you want a quick base collection that you can layer re-ordered UI lists on top of, you might want to look into a balanced sorted tree, rather than a hashset.

What are the advantages of Sets and set based operations?

I know what Sets are and common operations on sets like union, intersection, difference, subset. However i don't understand in which situations are set based operations desired? Any real world examples? What are the advantages of using set vs using a list or a Hash? If i have two lists then i can find the union,intersection of those lists too. So why use Sets?
Edit
I specifically want to know real world situations where i should use a set instead of a list.
Set guarantees there there is no duplicate object in it. List doesn't so you can have multiple entries of "equal" objects in a list. There are million of things that you can use set and it will make your life much easier, for example, a set of countries, a set of username, etc. If you use a list to store these data, you will need to check whether your list has already contained the same element or not before adding the new one unless the list is allowed to have duplicates.
In other words, set may be considered as a list without any duplicates. However, the interface of Set and List aren't really the same in Java. For example, you aren't able to get the element at certain position in a set. This is because position is not important in the set (but it is for a list). Therefore, selecting which data collection to use depends entirely on the purpose.
I, myself, found that Set is very useful in many cases and reduces the amount of checking for duplicates. One of my use cases is to use set to find how many chemical elements are in a molecule. The molecule contains a list of atom objects and each atom is associated to a element symbol so in order to find the type of element, I loop over all the atoms and add the element to an element set. All the duplicates are removed without hassle.
Among other things, sets typically guarantee access times of O(logN). They also enforce only one entry with a given value (by throwing exceptions when you try to add a duplicate).
Hashes typically offer O(1) access, but do not guarantee uniqueness.

Categories