Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C#/PHP] Datastructuur voor recursie?

Pagina: 1
Acties:

  • las3r
  • Registratie: Augustus 2006
  • Laatst online: 22-11 13:04
Hoi allemaal,

Ik heb een zestal jaren ervaring met php, en ben recentelijk begonnen met het ontwikkelen in ASP.NET MVC. Ik ben volledig bekend met OO-programmeren, en ik heb er veel lol in :)

Echter loop ik nu tegen wat geavanceerdere problemen aan waar ik geen eenduidig antwoord op kan vinden: recursie.

In een project waar ik nu mee bezig ben heb ik een soort van file-structure opgeslagen in een relationele DB (SQL Server). Stel het je even zo voor:

code:
1
FileId - FileName - FileType (file/folder) - ParentId


Een file kan dus children hebben zodat er een soort van directorystructuur ontstaat.

Het probleem waar ik tegen aan loop is het volgende:
Vanuit PHP ben ik gewend dat ik lekker array's mag aanmaken, en daar van alles in kan stoppen. Een array opbouwen met daarin een volledige file structure is dan ook geen probleem in php. In C# lukt het me om de juiste structuur (name, children, 'depth level') naar de debugger console weg te 'printen'. So far so good.

Ik kom in de problemen als ik deze gehele structuur als een object wil returnen. Wat voor object ? Hoe moet ik dit gaan doen? C# verwacht bij arrays altijd een grootte, en ik weet niet hoe diep de tree gaat worden (Geen max).

Het liefst zie ik
code:
1
2
3
[0] = array ( fileId => x .......snip ........
              files = array( fileId => y ...... snip ....));
etcetera


Ik heb zelf al rondgekeken op StackOverflow, en wat directe collega's gevraagd, maar niemand schijnt hier eenduidig een antwoord op te hebben.Verder weet ik dat je ook gewoon eerst de root kunt laden, dan alle folders die hier onder vallen, om een 'on-demand' file structuur te tonen zeg maar, maar het gaat mij hier niet om de implementatie, puur om het 'hoe' en 'waarom'.

Ik ben niet op zoek naar een stuk code die dit voor mij oplost, maar naar de weg naar de oplossing, zodat ik het zelf kan gaan uitzoeken en bouwen.

Note: Ik heb nog nooit gewerkt met Generic Types en trees, of andere (voor mij geavanceerde) zaken binnen C#.

[ Voor 2% gewijzigd door las3r op 27-07-2013 08:33 . Reden: Extra info ]


  • Robbiedobbie
  • Registratie: Augustus 2009
  • Laatst online: 16:27
Wat je kan doen is een soort van node class maken met de info van de node die je wil en waar je een arraylist van children bijhoudt (Type node), waardoor je gewoon een tree structuur als data structure gebruikt.

Kijk ook hier eens naar, als je opzoek bent naar zoiets:

Wikipedia: List of data structures

  • Phyxion
  • Registratie: April 2004
  • Niet online

Phyxion

_/-\o_

Tsja, je kan hier natuurlijk meerdere manieren voor gebruiken maar een tree/graph zit er natuurlijk erg dicht bij. Je zou bijvoorbeeld QuickGraph (http://quickgraph.codeplex.com/) kunnen gebruiken. Je kan ook een LinkedList (MSDN: LinkedList(T) Class (System.Collections.Generic)) gebruiken, alleen zal er je er dan waarschijnlijk wat om heen moeten schrijven. Maar goed, "returnen" is een beetje vaag. Returnen naar wat? Wat wil je dan doen met de data?

'You like a gay cowboy and you look like a gay terrorist.' - James May


  • Daos
  • Registratie: Oktober 2004
  • Niet online
Je kan aparte File en Folder objecten maken waarbij Folder van File afstamt en meerdere File objecten kan bewaren bv in een SortedSet:
C#:
63
private SortedSet<File> files = new SortedSet<File>();


Tijdens het bouwen van de structuur moet je bijhouden welke Folder-objecten bij welke ID's horen. Dat kan je hierin opslaan (voorwaarde is dat folders eerder voorkomen dan files in die folder; loopt het door elkaar, dan moet je iets anders verzinnen):
C#:
101
SortedList<int, Folder> folders = new SortedList<int,Folder>();


Na het bouwen bevat de root-folder de hele directory-structuur. Als die het ID van 0 heeft haal je hem zo uit de eerder genoemde tijdelijke folders-lijst:
C#:
132
133
Folder root;
folders.TryGetValue(0, out root);

[ Voor 0% gewijzigd door Daos op 27-07-2013 11:04 . Reden: Code gefixt; door elkaar bleek ook simpel en met zelfde lijst te doen ]


  • Matis
  • Registratie: Januari 2007
  • Laatst online: 20:57

Matis

Rubber Rocket

Als ik data moet nesten en ordenen gebruik is praktisch altijd "The Nested Set Model". Er is voor PHP / MySQL en C# legio voorbeeldcode voor te vinden.
Wanneer je met multiple roots werkt, zijn de mogelijkheden ongekend groot :)

Zomaar wat zoekresultaten:
http://www.codeproject.co...ted-Set-Model-Treebuilder
http://mikehillyer.com/ar...erarchical-data-in-mysql/

[ Voor 27% gewijzigd door Matis op 27-07-2013 10:28 ]

If money talks then I'm a mime
If time is money then I'm out of time


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

las3r schreef op zaterdag 27 juli 2013 @ 08:20:
Note: Ik heb nog nooit gewerkt met Generic Types en trees, of andere (voor mij geavanceerde) zaken binnen C#.
Dan wordt dat hoog tijd! :) Ik bedoel het niet vervelend hoor, maar dit is zulke basiskennis dat het misschien tijd wordt om te leren programmeren. Pak een boek. Dit is meestal hoofdstuk 2.

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 20:01
Zoijar schreef op zaterdag 27 juli 2013 @ 10:42:
[...]. Dit is meestal hoofdstuk 2.
Probeer hoofdstuk 11 :P Granted het is een uitvoerig boek, maar ze vonden het genoodzaakt om toch eerst 420 pagina's aan andere zaken te besteden zoals: data types, operators & control flow, flow control, methods, classes, inheritance, value types, well-formed types en exception handling. IMO ook beter dan meteen in hoofdstuk 2 generics laten vallen.

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Ik bedoelde niet specifiek generics, maar data structuren iha.

  • las3r
  • Registratie: Augustus 2006
  • Laatst online: 22-11 13:04
Allereerst thanks voor alle antwoorden :) Ik ga er mee aan de slag.
Zoijar schreef op zaterdag 27 juli 2013 @ 10:42:
[...]

Dan wordt dat hoog tijd! :) Ik bedoel het niet vervelend hoor, maar dit is zulke basiskennis dat het misschien tijd wordt om te leren programmeren. Pak een boek. Dit is meestal hoofdstuk 2.
Ik ben net afgestudeerd en heb sloten ervaring met php, OO en java (C# zat niet in ons curriculum). Het is ook zeer zeker mijn plan om dieper in C# te duiken :-)
Phyxion schreef op zaterdag 27 juli 2013 @ 10:11:
Tsja, je kan hier natuurlijk meerdere manieren voor gebruiken maar een tree/graph zit er natuurlijk erg dicht bij. Je zou bijvoorbeeld QuickGraph (http://quickgraph.codeplex.com/) kunnen gebruiken. Je kan ook een LinkedList (MSDN: LinkedList(T) Class (System.Collections.Generic)) gebruiken, alleen zal er je er dan waarschijnlijk wat om heen moeten schrijven. Maar goed, "returnen" is een beetje vaag. Returnen naar wat? Wat wil je dan doen met de data?
Deze data wil ik via een jquery 'ophalen' als JSON. Ik weet dat dit in theorie moet kunnen. Uiteraard is de meeste handige manier om eerst de root folders te laten zien, onclick de subfolders/files te laten zien, maar ik vroeg me enkel af hoe ik het zou moeten doen als ik wél alles in een keer zou willen ophalen.

Nogmaals thanks - ik ga aan de slag.

  • BikkelZ
  • Registratie: Januari 2000
  • Laatst online: 21-02 08:50

BikkelZ

CMD+Z

Even een kleine generieke opmerking over je vraag:

Je bent gewend om met arrays alles te kunnen in PHP, terwijl ze in C# een beetje richting C en Visual Basic zitten en heel rigide zijn. In C# gebruik je eigenlijk zelden een array maar pak je standaard een List, en eigenlijk altijd maak je die ook typed (dus List<string> bijvoorbeeld). Wil je verschillende dingen opslaan, sla je die op in een losse klasse en je stopt dus niet hele verschillende in een array (dat kan natuurlijk ook in PHP, maar het hoéft niet). Ik lees dat je Java gedaan hebt, volgens mij heet het dan een Vector in plaats van een List.

Je kunt een aanpak over trees overnemen van iemand op het web of zelf iets in elkaar draaien. Cruciaal is het om de generieke dingen generiek te houden en de specifieke zaken alleen te coden. Als je het simpel wil houden kun je het zien als objecten die een List hebben met daarin weer objecten van het zelfde type of afgeleid van het zelfde type. Zo kun je dus recursief door een eindeloos diep geneste datastructuur heen lopen en ook weer opbouwen.

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class NestableList
{
    public List<NestableList> subLists;
    // Wellicht wil je nog wat meer velden in deze class hebben

    public NestableList(List<NestableList> subLists)
    {
        this.subLists = subLists;
        // Voeg hier de gegevens van je extra velden toe
    }

    // Voorbeeld van recursief door je tree heen lopen
    public override string ToString()
    {
        StringBuilder classInfo = new StringBuilder("something interesting about this class.");
        foreach (NestableList subList in this.subLists)
        {
            classInfo.Append(subList.ToString());
        }

        return classInfo.ToString();
    }
}


Je kunt er ook voor kiezen om die NestableList weer te overerven en er wijzigingen in aan te maken op het moment dat bijvoorbeeld je per niveau wel weer een andere manier van renderen wil hebben of iets meer gegevens opslaan. Maar er zijn legio manieren om dit op te lossen en er zijn waarschijnlijk ook wel hordes betere voorbeelden of kant en klaar frameworkjes te vinden die dit voor je oplossen.

iOS developer


  • epic007
  • Registratie: Februari 2004
  • Laatst online: 17-11 15:31
Klinkt als het Composite pattern:

Afbeeldingslocatie: http://upload.wikimedia.org/wikipedia/commons/thumb/5/5a/Composite_UML_class_diagram_%28fixed%29.svg/600px-Composite_UML_class_diagram_%28fixed%29.svg.png

http://en.wikipedia.org/wiki/Composite_pattern
http://www.dofactory.com/Patterns/PatternComposite.aspx

[ Voor 35% gewijzigd door epic007 op 30-07-2013 09:28 ]

Pagina: 1