Hierarchy vs Merged List - c#

Basically in my app I want to store all the nodes created by the user in a global list, say like:
GlobalComposition = { collection }
which will store nodes like:
ImageInput01, ImageInput02, Blur01, Sharpen01, Contrast01, Contrast02
What I can't decide is whether I should store them in a linear "1 dimensional" collection, or only store the base node that contains other nodes? So for something like:
ImageInput01 -> Blur01 -> Sharpen01 -> Contrast01
storing only ImageInput01.
This gives me the ability to use the same names for the action nodes that comes after the base node.
Which one would be better for unique naming system for nodes, performance, easily traversing the nodes in the composition, etc?
To me keeping the hierarchy seems more sensible but want to know people's thoughts.

Certainly a hierarchy will give you more power from a taxonomy point of view. Also, searching a tree is more efficient than searching a 1-dimensional collection in most cases.
You'd also be able to use .ToList() for a 1-dimensional collection as long as you're using .NET generic collections, as well.
Unfortunately, a hierarchy is a bit harder to implement, but generally if there is an indication of a need for it, you'll be able to take good advantage of the features it'll provide you way down the line.

Related

Should I use linked list or list and how do I serialize it.

This is for c#
I'm an old dinosaur, writing 360 assembler since the 70's, trying to write stuff for the PC. Along the way I am replacing my old write it myself thinking with use the existing infrastructure.
Here is what I have now. Two objects, System and Planet. A field in System has a pointer to the next System, there is also a second chain of Systems that meet current selection criteria. Also System has a pointer to Planet and Planet has a pointer to the next Planet. Planet also has a chain of all planets.
Now the questions. Should I use lists and have C# handle all the linking etc. I'm fairly sure 1 object instance can be in multiple lists, so I can have 1 list of all systems and a second list of selected systems. Plus have a list of Planets in the system and another list of all Planets.
I also want to save this mess to disk. I've spent some time looking at serialization and it appears to be great at saving all the instances in a list, but things break down when you want to serialize multiple classes. Am I missing something basic, just a yes will send me back to looking, or do I have to roll my own?
I don't want code examples, just a gentle puch in the direction I should be looking at.
I would simply create two classes, one being the System with a List<Planet> containing all its planets and the other one being the Planet, containing a reference to his system (if one is required). The systems are themselves saved in a List<System>. Like the planets they could hold a reference to their parent so they have access to the list, but if they don't need to, its fine.
Saving this stuff should be three lines of code with a serializing system of your choice, either in text or binary (Json.Net, the Xml stuff .Net provides, yaml, binary formatter...).
Linked lists are not worth the implementation, they aren't as useful as dynamic arrays (like the List<T> in System.Collections.Generic or the Vector<T> in C++) which resize themselves when needed, and they aren't that easy to keep track of. They definetly have applications but this is not one of them IMO.
Should I use linked list or list...
The answer depends on what your object represents and how you are going to use it. For example, if I was representing houses, and the people who live at each house; then I might choose to have a collection of House objects. I'm using collection as a generic term there: specifically, I would probably use List<T> from the System.Collections.Generic namespace (where T can represent any type, so it would be a List<House> in this case), unless I needed something more specific like a Stack<T>, Queue<T>, Dictionary<T,U>, etc, etc.
Notice how in this approach, each House doesn't know which house is next, because the whole concept of 'next' relates to the collection of houses: each individual house doesn't need to know where it is in the collection - that's the responsibility of the collection. This is a design principle called "separation of concerns".
For example, if I wanted to create a different collection of House objects (e.g. the ones with red front doors), I could do so by creating a new collection, referring to the same House objects; whereas with the approach mentioned of an object having a reference to the next one, I would have to create a different House object because the next value would be different in those two collections.
Using List<T> allows you to focus on writing your classes, instead of having to write the implementation of the collection.
There are also performance reasons against using linked lists unless you only plan to access the data in sequential order.
Each House has-a collection of people. So I might put a property on House called People, of type List<Person>. And if I needed to get to the house that the person was associated with, I could have a property on Person called House, of type House.
I hope this structure of Houses and People corresponds to your scenario with Systems and Planets.
Maybe also worth looking at When should I use a List vs a LinkedList
...and how do I serialize it.
Plenty on the internet, try these...
How to Serialize List<T>?
https://www.thomaslevesque.com/2009/06/12/c-parentchild-relationship-and-xml-serialization/
Hope this helps to get you started.
From the sound of it, I will create class of System, Planet with one to many reference of planets in System (List here). In order to avoid strong coupling between System and Planet, One can look at Chain of Responsibility pattern.
Saving this data to database one can serialise using Json.Net (newtonsoft). SQL server supports directly putting json array.
Pseudo code:
class Planet {
public Planet(System system) {System = system;}
public System System {get; private set;} // singleton
}
class System {
public Planet Planet {get; set;}
// list of planets
private List<Planet> planets = new List<Planet>();
public List<Planet> Planets { get {return planets; } }
}

C# custom file parsing with 2 delimiters and different record types

I have a (not quite valid) CSV file that contains rows of multiple types. Any record could be one of about 6 different types and each type has a different number of properties. The first part of any row contains the timestamp and the type of record, followed by a standard CSV of the data.
Example
1456057920 PERSON, Ted Danson, 123 Fake Street, 555-123-3214, blah
1476195120 PLACE, Detroit, Michigan, 12345
1440581532 THING, Bucket, Has holes, Not a good bucket
And to make matters more complex, I need to be able to do different things with the records depending on certain criteria. So a PERSON type can be automatically inserted into a DB without user input, but a THING type would be displayed on screen for the user to review and approve before adding to DB and continuing the parse, etc.
Normally, I would use a library like CsvHelper to map the records to a type, but in this case since the types could be different, and the first part uses a space instead of comma, I dont know how to do that with a standard CSV library. So currently how I am doing it each loop is:
String split based off comma.
Split the first array item by the space.
Use a switch statement to determine the type and create the object.
Put that object into a List of type object.
Get confused as to where to go now because i now have a list of various types and will have to use yet another switch or if to determine the next parts.
I don't really know for sure if I will actually need that List but I have a feeling the user will want the ability to manually flip through records in the file.
By this point, this is starting to make for very long, confusing code, and my gut feeling tells me there has to be a cleaner way to do this. I thought maybe using Type.GetType(string) would help simplify the code some, but this seems like it might be terribly inefficient in a loop with 10k+ records and might make things even more confusing. I then thought maybe making some interfaces might help, but I'm not the greatest at using interfaces in this context and I seem to end up in about this same situation.
So what would be a more manageable way to parse this file? Are there any C# parsing libraries out there that would be able to handle something like this?
You can implement an IRecord interface that has a Timestamp property and a Process method (perhaps others as well).
Then, implement concrete types for each type of record.
Use a switch statement to determine the type and create and populate the correct concrete type.
Place each object in a List
After that you can do whatever you need. Some examples:
Loop through each item and call Process() to handle it.
Use linq .OfType<{concrete type}> to segment the list. (Warning with 10k
records, this would be slow since it would traverse the entire list for each concrete type.)
Use an overridden ToString method to give a single text representation of the IRecord
If using WPF, you can define a datatype template for each concrete type, bind an ItemsControl derivative to a collection of IRecords and your "detail" display (e.g. ListItem or separate ContentControl) will automagically display the item using the correct DataTemplate
Continuing in my comment - well that depends. What u described is actually pretty good for starters, u can of course expand it to a series of factories one for each object type - so that you move from explicit switch into searching for first factory that can parse a line. Might prove useful if u are looking to adding more object types in the future - you just add then another factory for new kind of object. Up to you if these objects should share a common interface. Interface is used generally to define a a behavior, so it doesn't seem so. Maybe you should rather just a Dictionary? You need to ask urself if you actually need strongly typed objects here? Maybe what you need is a simple class with ObjectType property and Dictionary of properties with some helper methods for easy typed properties access like GetBool, GetInt or generic Get?

Collections for hierarchies

In the app I am writing, I am trying to find a way to store hierarchies effectively. Here is an example.
At the bottom, you can see the nodes to be stored. Should I use multi dimensional lists? That doesn't seem very optimal, right? I was thinking holding references like so:
node.Parent
node.Children { collection }
Anyone has experience with this kind of stuff?
This is a fairly basic implementation of a tree, yes. If choose to make your collection for the children an IList or IEnumable or ArrayList, etc is up to you.
I would strongly suggest you build a generic implementation instead of one typed to your domain model, however that is up to you.
Yeah. You have the right idea. If you need a two-directional hierarchy, I wouldn't use a multi-dimensional list... I would add a node to the tree and each node contains a parent and a collection of children.
You are on the right track.
If not all items are of the same type, I may use an abstract base class for a linked list and children collections in such a situation.

LINQ to XML, ORM or something "Completely Different"?

I'm working on a Silverlight Project with all the features and limitations that entails. This is an update to a previous product. The intent, in order to be quick to market, is to maintain as much of the back-end (webservices, database, etc..) as at all possible. Our mandate it to only touch the back-end if there is no other way. We'll primarily be focused on re-writing the front-end. There's an important industry conference soon where we will want to demo the early look of the product. There may be time prior to the official release to do some re-work, but the back-end may need to wait until V2.
OK, so what I'm trying to do is use the MVVM pattern with data binding for the front-end for which I'm responsible (MVVM pattern is dictated from above). I have a pre-existig web service that serves up some XML. A sample of that XML looks like is below:
<CODEBOOKINDEX>
<ME Words="1" Score="25" Highscore="1">Main Entry Item
<NM>attack</NM>
<NM>cardiac</NM>
<NM>chest</NM>
<NM>effort</NM>
<NM>heart</NM>
<NM>pectoris</NM>
<NM>syndrome</NM>
<NM>vasomotor</NM>
<IE>413.9</IE>
<M1 Words="1" Score="25">An M1 Item (Same as ME, just first level Child)
<IE>557.1</IE>
</M1>
<M1 Words="1" Score="25">Another M1 Item
<IE>443.9</IE>
<M2 Words="1" Score="25">An M2 Item (again same as ME, just a child of an M1 item)
<CF>Arteriosclerosis,extremities</CF>
<IE>440.20</IE>
</M2>
</M1>
</ME></CODEBOOKINDEX>
So, my question, since I want to bind this to a UI using the MVVM pattern, it seems to me that I need to translate this into a custom object. As you can see there are a number of "Entry" items, MainEntry (ME) and Subentries (M1 or M2 in this example), these will all contain certain other nodes (they will all have an IE node, for example), they MAY contain 0 or more other node types (for example they MAY or may not contain one or more NM nodes, or they MAY contain one CF node or not). Whihc means (at least to me) that I can't really bind directly to XML because:
It violates the MVVM pattern (I could probably justify this for the demo, but would have to refactor later).
I can't really bind a UI element to an XML node that MAY not be there for a given item.
In some cases Ihave to translate a collection (a bunch of NM items, for example) into a formated strig for display purposes, which I don't THINK is a trivial thing.
So, I'm trying to understand the best way to translate this XML into a bindable object, which in my mind means transforming this XML into an object for the model and then overlaying a view-model on that model.
Can this be done easily with LINQ to XML queries, or am I really moving into the realm of an ORM such as NHibernate or Entity Framework (no holy wars about WHICH ORM please)?
I've only just established what controls I will be using for UI and I need to demonstrate to my manager rather quickly HOW I'm going to handle the translation.
So, the real questions:
Do I NEED an ORM? I'm not against using them, but I want to keep the size of the XAP file small and want to limit the amount of new tech I (and my teammates) need to learn in a single pass.
If I do need one, can I keep the file size down and can I ramp up quickly with either EF or NHibernatge and have a model to show very soon? I'm talking like a week here to have SOMETHING that will take output from the webservice and turn it into an object, even if the map isn't perfect initially, I need to demonstrate some progress.
Is there another option alltogether that I'm not considering that might be easier, limit the need to modify existing code (i.e. the webservice) and product usable results?
Do I NEED an ORM?
No. You aren't mapping to a relational source, so an object relational mapper won't help.
Get it done with Linq to Xml.
public CustomClass TranslateME(XElement source)
{
CustomClass result = new CustomClass();
result.Words = (int) source.Attribute("Words");
result.Score = (int) source.Attribute("Score");
XAttribute highScore = source.Attribute("HighScore");
result.HighScore = (highScore == null) ? 0 : (int) highScore;
result.NMs = source
.Elements("NM")
.Select(x => x.Value)
.ToList();
result.IE = source
.Element("IE").Value;
result.SubEntries = source
.Elements("M1")
.Select(x => TranslateM1(x))
.ToList();
return result;
}

Walking an XML tree in C#

I'm new to .net and c#, so I want to make sure i'm using the right tool for the job.
The XML i'm receiving is a description of a directory tree on another machine, so it go many levels deep. What I need to do now is to take the XML and create a structure of objects (custom classes) and populate them with info from the XML input, like File, Folder, Tags, Property...
The Tree stucture of this XML input makes it, in my mind, a prime candidate for using recursion to walk the tree.
Is there a different way of doing this in .net 3.5?
I've looked at XmlReaders, but they seem to be walking the tree in a linear fashion, not really what i'm looking for...
The XML i'm receiving is part of a 3rd party api, so is outside my control, and may change in the futures.
I've looked into Deserialization, but it's shortcomings (black box implementation, need to declare members a public, slow, only works for simple objects...) takes it out of the list as well.
Thanks for your input on this.
I would use the XLINQ classes in System.Xml.Linq (this is the namespace and the assembly you will need to reference). Load the XML into and XDocument:
XDocument doc = XDocument.Parse(someString);
Next you can either use recursion or a pseudo-recursion loop to iterate over the child nodes. You can choose you child nodes like:
//if Directory is tag name of Directory XML
//Note: Root is just the root XElement of the document
var directoryElements = doc.Root.Elements("Directory");
//you get the idea
var fileElements = doc.Root.Elements("File");
The variables directoryElements and fileElements will be IEnumerable types, which means you can use something like a foreach to loop through all of the elements. One way to build up you elements would be something like this:
List<MyFileType> files = new List<MyFileType>();
foreach(XElelement fileElement in fileElements)
{
files.Add(new MyFileType()
{
Prop1 = fileElement.Element("Prop1"), //assumes properties are elements
Prop2 = fileElement.Element("Prop2"),
});
}
In the example, MyFileType is a type you created to represent files. This is a bit of a brute-force attack, but it will get the job done.
If you want to use XPath you will need to using System.Xml.XPath.
A Note on System.Xml vs System.Xml.Linq
There are a number of XML classes that have been in .Net since the 1.0 days. These live (mostly) in System.Xml. In .Net 3.5, a wonderful, new set of XML classes were released under System.Xml.Linq. I cannot over-emphasize how much nicer they are to work with than the old classes in System.Xml. I would highly recommend them to any .Net programmer and especially someone just getting into .Net/C#.
XmlReader isn't a particularly friendly API. If you can use .NET 3.5, then loading into LINQ to XML is likely to be your best bet. You could easily use recursion with that.
Otherwise, XmlDocument would still do the trick... just a bit less pleasantly.
This is a problem which is very suitable for recursion.
To elaborate a bit more on what another poster said, you'll want to start by loading the XML into a System.Xml.XmlDocument, (using LoadXml or Load).
You can access the root of the tree using the XmlDocument.DocumentElement property, and access the children of each node by using the ChildNodes property. Child nodes returns a collection, and when the Collection is of size 0, you know you'll have reached your base case.
Using LINQ is also a good option, but I'm unable to elaborate on this solution, cause I'm not really a LINQ expert.
As Jon mentioned, XmlReader isn't very friendly. If you end up having perf issues, you might want to look into it, but if you just want to get the job done, go with XmlDocument/ChildNodes using recursion.
Load your XML into an XMLDocument. You can then walk the XMLDocuments DOM using recursion.
You might want to also look into the factory method pattern to create your classes, would be very useful here.

Categories

Resources