Click here to Skip to main content
15,868,141 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
Hi all,
I'm having a little trouble with a bit of code I just wrote.
It's in an ASP.NET MVC application, so I can handle the following scenario back-end (C#) or front-end (JavaScript). It shouldn't really matter for the used method though.
Basically what I'm trying to do is the following:

I have the following list (third party component, can't change this):
Marker 1 start
Some object 1
Some object 2
Some object 3
Marker 1 end
Marker 2 start
Some object 4
Marker 3 start
Some object 5
Marker 3 end
Marker 2 end
Some object 6


And I want the following structure:
Marker 1
   Some object 1
   Some object 2
   Some object 3
Marker 2
   Some object 4
   Marker 3
      Some object 5
Anonymous marker
   Some object 6


So as I see it I can do the following (pseudo code):
markers;
currentMarker;
foreach (obj in list)
switch (obj)
{
   case 'Marker start':
      newMarker = new {...};
      if (currentMarker != null) {
         currentMarker.markers.add(newMarker);
         newMarker.parent = currentMarker;
      } else {
         markers.add(newMarker);
      }
      currentMarker = newMarker;
   case 'Marker end':
      if (currentMarker.parent) {
         currentMarker = currentMarker.parent;
      } else {
         currentMarker = null;
      }
   default:
      if (currentMarker == null) {
         currentMarker = new anonymous Marker {...};
         markers.add(currentMarker);
      }
      currentMarker.objects.add(obj);
}
return markers;
That's a lot of cases and if's and else's...
My method is already over 40 lines of code and I'm pretty sure I'll add some lines and if's as time passes (what if a Marker start has no end marker? etc.).
Is there a better, more readable, more maintainable way to handle the scenario? Maybe some pattern or algorithm that can save the day?
I can't be the first one to have this problem :)

Thanks!
Posted
Updated 18-Nov-15 0:36am
v2
Comments
BillWoodruff 18-Nov-15 22:23pm    
An important factor here is whether you are sure the source list is "well-formed:" no "hanging markers" left "unclosed;" no marker getting "closed" while its "interior nodes" are still "unclosed." Other than that looks like a simple problem of creating a tree-structure.
Sander Rossel 19-Nov-15 3:20am    
"Simply" creating a tree-structure is easier said than done :)
And no, my source may not be well-formed, it's turning out to be quite a PITA... :(

1 solution

Why not use a more structured way of representing the data in the first place? Like using JSON, XML or YAML for example.

-------------------------------

Every time you encounter something a start marker you push it onto the stack, increase the ident of the IndentedTextWriter and write the marker text to it. For every end marker you pop the stack and compare this marker number with the end marker number (and give an error if the numbers don't match). You then also decrease the ident of the writer. Every other item you just write to the IndentedTextWriter. When you encounter an item at the root outside a marker you add a Anonymous marker.

Hope this gives you a good idea on how to approach processing the file.

https://msdn.microsoft.com/en-us/library/system.collections.stack%28v=vs.110%29.aspx[^]

https://msdn.microsoft.com/en-us/library/system.codedom.compiler.indentedtextwriter%28v=vs.110%29.aspx[^]

Good luck!
 
Share this answer
 
v2
Comments
Sander Rossel 18-Nov-15 6:35am    
I can't change the underlying data structure, that would present a whole lot of problems (code-wise, project-wise, financial-wise, etc...).
I'm getting the data how it is and it's up to me to do anything with it.
E.F. Nijboer 18-Nov-15 9:26am    
I understand. I can see some structure but don't understand where "Anonymous marker" comes from. There is no way I could guess this from the original source. It seems like a closing marker is seen as a separate marker, right? Or is this the desired output? How to determine it should be an Anonymous marker?
Sander Rossel 18-Nov-15 10:30am    
All objects that are not enclosed by start/end markers go into some anonymous marker (a placeholder if you like).
Multiple objects could go in the same anonymous marker.
E.F. Nijboer 18-Nov-15 12:56pm    
Ah, I see. I would advise to use a stack. It makes it very easy to keep track of the markers and makes it easy to validate the file. You can use an IndentedTextWriter to produce the formatted output.
I updated the answer with more on how you could process the source list.
Sander Rossel 18-Nov-15 13:31pm    
Thanks, that gave some good ideas!
Marked as solution and rated 5.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900