Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    86

    [C#] disaegnare menù html da tabella mysql

    Ciao a tutti e grazie per l'attenzione che mi state per dedicare spero che questa discussione possa essere utile anche per altri utenti, quindi ecco il mio quesito. Data una tabella MySql con colonne 5 così descritte id(int auto_increment), nome(varchar), parent_id(int), sub_cat(int), descrizione(varchar), dove le categorie vengono registrate a valore parent_id 0 e le sottocategorie assumono per questo valore il numero id delle prime corrispondenti. E' possibile attraverso il linguaggio C# su .NET generare un menù che tenga conto di categorie e sotto categorie N finite senza utilizzare il ciclo FOR o un loop in generale? Ho letto qualche query di tipo LINQ ma non sono riuscito ad ingegnerizzare una adatta. Grazie ancora per l'attenzione un saluto a tutti.

  2. #2

    Moderazione

    Le discussioni relative a C# non sono trattate qui, ma nella sezione Visual Basic e .Net Framework; provvedo a spostare il thread.


    ---

    Venendo al tuo problema, non mi è molto chiaro il requisito di non usare loop... è una richiesta di qualche esercizio o c'è qualche altro motivo?
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    86
    Ciao, chiedo subito scusa per l'errore di inserimento della discussione e ti ringrazio per l'efficenza e la cortesia. Dunque per rispondere alla tua domanda dico che principalmente è un motivo di studio ma anche pratico visto che con i loop riesco sempre ad arrivare ad un numero finito, diciamo x per comodità, di profondità cioè non mi permette di rendere efficiente la soluzione che sto cercando di programmare. Hai idee in merito?

  4. #4
    Puoi usare tranquillamente una soluzione ricorsiva... In pseudocodice (più-o-meno-Python) sarebbe una cosa del tipo:
    codice:
    def printItems(lista, parentID):
        print '<ul>'
        for elem in lista:
            if elem.parentID==parentID:
                print '<li>', elem.name, '</li>'
                printItems(lista, elem.id)
        print '</ul>'
    (in realtà si potrebbe rendere più efficiente memorizzando i dati in un dictionary con chiave il parentid, ma è per rendere l'idea)
    Ultima modifica di MItaly; 01-07-2014 a 00:17
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2006
    Messaggi
    86
    Quote Originariamente inviata da MItaly Visualizza il messaggio
    Puoi usare tranquillamente una soluzione ricorsiva... In pseudocodice (più-o-meno-Python) sarebbe una cosa del tipo:
    codice:
    def printItems(lista, parentID):
        print '<ul>'
        for elem in lista:
            if elem.parentID==parentID:
                print '<li>', elem.name, '</li>'
                printItems(lista, elem.id)
        print '</ul>'
    (in realtà si potrebbe rendere più efficiente memorizzando i dati in un dictionary con chiave il parentid, ma è per rendere l'idea)
    Grazie per la risposta, dunque ad una versione di codice ricorsiva simile a quella proposta da te ero arrivato anche io il problema è che con questo codice arrivi a due profondita (Padre -> Figlio) ma se invece ad esempio ci fosse una situazione a 3 profondità tipo (Padre -> Figlio -> Figlio) con quello script non vedrei il 3 livello e nemmeno un possibile N livello. Ecco perchè mi sto spingendo a cercare una soluzione più efficiente.

  6. #6
    None, il codice è ricorsivo, può arrivare a profondità arbitraria (in pratica limitata ovviamente dalle dimensioni dello stack). Per fare un menu a più livelli basta impostare in maniera adeguata il parentID; ad esempio
    codice:
    ID      ParentID    Nome
    1       0           Foo
    2       0           Bar
    3       1           Baz
    4       1           Quux
    5       2           Asd
    6       3           Qwerty
    dà come risultato
    • Foo
      • Baz
        • Qwerty
      • Quux
    • Bar
      • Asd
    Ultima modifica di MItaly; 01-07-2014 a 01:21
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,590
    Quote Originariamente inviata da MItaly Visualizza il messaggio
    Puoi usare tranquillamente una soluzione ricorsiva... In pseudocodice (più-o-meno-Python) sarebbe una cosa del tipo:
    codice:
    def printItems(lista, parentID):
        print '<ul>'
        for elem in lista:
            if elem.parentID==parentID:
                print '<li>', elem.name, '</li>'
                printItems(lista, elem.id)
        print '</ul>'
    (in realtà si potrebbe rendere più efficiente memorizzando i dati in un dictionary con chiave il parentid, ma è per rendere l'idea)
    Certo che in realtà scorri tutta la lista un numero impressionante di volte per il compito da risolvere e ci sono soluzioni possibili in 2 passaggi (e una struttura di supporto).

    Vero è anche che in generale, per le dimensioni di un menù, non si presenterà alcun problema e non c'è gran spreco di risorse.
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  8. #8
    Quote Originariamente inviata da Scara95 Visualizza il messaggio
    Certo che in realtà scorri tutta la lista un numero impressionante di volte per il compito da risolvere e ci sono soluzioni possibili in 2 passaggi (e una struttura di supporto).

    Vero è anche che in generale, per le dimensioni di un menù, non si presenterà alcun problema e non c'è gran spreco di risorse.
    Ovviamente concordo su entrambe le considerazioni, era più che altro per rendere l'idea. La soluzione più corretta probabilmente sarebbe una multimap (parentID -> (ID, Nome)), in cui l'accesso agli elementi desiderati è O(1).
    codice:
    string buildMenu(Element elem[])
    {
        Dictionary<int, List<Element> > d;
        foreach(Element e in elem)
        {
            if(!d.ContainsKey(e.parentID))
                d[parentID]=new List<Element>();
            d[parentID].Add(e);
        }
        StringBuilder sb;
        buildItems(d, 0, sb);
        return sb.toString();
    }
    
    void buildItems(Dictionary<int, List<Element> > d, int parentID, StringBuilder sb)
    {
        sb.Append("<ul>");
        List<Element> l = d[parentID];
        foreach(Element e: l)
        {
            sb.Append("<li>");
            sb.Append(e.name);
            buildItems(d, e.ID, sb);
            sb.Append("</li>");
        }
        sb.Append("</ul>");
    }
    Ultima modifica di MItaly; 01-07-2014 a 15:25 Motivo: Ricorsione persa per strada :-/
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,590
    Quote Originariamente inviata da MItaly Visualizza il messaggio
    Ovviamente concordo su entrambe le considerazioni, era più che altro per rendere l'idea. La soluzione più corretta probabilmente sarebbe una multimap (parentID -> (ID, Nome)), in cui l'accesso agli elementi desiderati è O(1).
    codice:
    string buildMenu(Element elem[])
    {
        Dictionary<int, List<Element> > d;
        foreach(Element e in elem)
        {
            if(!d.ContainsKey(e.parentID))
                d[parentID]=new List<Element>();
            d[parentID].Add(e);
        }
        StringBuilder sb;
        buildItems(d, 0, sb);
        return sb.toString();
    }
    
    void buildItems(Dictionary<int, List<Element> > d, int parentID, StringBuilder sb)
    {
        sb.Append("<ul>");
        List<Element> l = d[parentID];
        foreach(Element e: l)
        {
            sb.Append("<li>");
            sb.Append(e.name);
            sb.Append("</li>");
        }
        sb.Append("</ul>");
    }
    Proprio di questo parlavo, l'avrei scritto io se ne avessi avuto il tempo. Tuttavia manca comunque parte della soluzione, una chiamata ricorsiva ci vuole comunque...
    (Ed ecco che perché le cose vanno scritte oltre che pensate, avevo tralasciato questo dettaglio)
    Resta comunque più efficiente.
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  10. #10
    Quote Originariamente inviata da Scara95 Visualizza il messaggio
    Proprio di questo parlavo, l'avrei scritto io se ne avessi avuto il tempo. Tuttavia manca comunque parte della soluzione, una chiamata ricorsiva ci vuole comunque...
    Wops, nella foga di reimpararmi le collection di C# mi ero perso la chiamata ricorsiva, ora dovrebbe essere corretto.
    (Ed ecco che perché le cose vanno scritte oltre che pensate, avevo tralasciato questo dettaglio)
    E aggiungo: ed ecco perché vanno provate oltre che scritte e pensate.
    Amaro C++, il gusto pieno dell'undefined behavior.

Tag per questa discussione

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.