C# ArrayMatrix/List

come al solito, appena prendo un po di confidenza con qualcosa subito cerco di strafare
(anche se al dir il vero, era una cosa già fatta altre volte sia con Py che con VBS)

// ArrayList = ArrayList in System.Collections
            Console.WriteLine(typeof(ArrayList));

            ArrayList arrList = new ArrayList() { "Matteo", 17, false };

            arrList.Add(new ArrayList() { "Marco", 18, true });

            arrList.Add(new ArrayList() { "Luca", 90, null });

            Console.WriteLine(arrList);

            for (int row = 0; row < arrList.Count; row++)
            {
                Console.WriteLine(arrList[row]);
            }

            Console.WriteLine(arrList[3]);

premessa: nel tutorial visto, questo tipo di operazione veniva fatta con gli ArrayMatrix
e quindi tramite i cicli annidati e gli indici venivano presi i valori degli Array detti Irregolari

io invece volevo fare la stessa cosa, ma con gli ArrayList che a differenza degli ArrayMatrix
e delle Liste possono utilizzare contemporaneamente valori misti invece di un Array di genere.

ora con i metodi visti non sono riuscito ad avere il risultato voluto riesco solo a stampare
il primo livello, ma con gli Array annidati mi ritorna il tipo System.Collections.ArrayList.

spero che ci sia un metodo che io non conosco per fare ciò che intendevo,
perché altrimenti l’unica strada che mi è venuta in mente è quella che
si va ad incapsulare gli ArrayList in un ArrayMatrix per poi iterarli. . .

credo che dovrebbe esserci un metodo una classe preposta a questo?

in pratica con gli ArrayList non mi fa iterare la matrice della lista tipo: arrList[3][2] ecc
infatti stampando arrList[3] mi torna System.Collections.ArrayList ma con arrList[3][2] da errore

ps arrList[3][2] dovrebbe essere il valore true della prima lista aggiunta
essendo che il valore terzo (quindi con indice 2) sarebbe il false messo nella fase di costruzione
mentre le altre due aggiunte invece vengono viste proprio come due liste e no come valori singoli.

Il tuo script mi da’ un output:

System.Collections.ArrayList
System.Collections.ArrayList
Matteo
17
False
System.Collections.ArrayList
System.Collections.ArrayList
System.Collections.ArrayList

C’e’ qualcosa che non va ? :slight_smile:

Che sarebbe ? … :confused:

Cioe’ ? … :confused:

Cosa ? … :confused:

OK, ma bisogna leggere cosa dice l’errore, e’ l’unico modo per capire cos’e’ che non va.
Dice:
error CS0021: Cannot apply indexing with [] to an expression of type ‘object’
Cioe’ non puo’ ricavare un elemento tramite le parentesi [] con un Object (perche’ ovviamente ci vuole un valore di un certo tipo … forse una IList … )

E’ perche’ quando estrai un elemento dalla ArrayList tramite le [], ottieni un Object:

ArrayList.Item[Int32] Property (System.Collections) | Microsoft Learn

Per stampare il valore che vuoi, devi fare un cast, cioe’ convertire quell’Object in una ArrayList
Cosi’ funziona:

    Console.WriteLine(((ArrayList)(arrList[3]))[2]);

EDIT

… Forse si puo’ togliere qualche parentesi, non so …
Io, nel dubbio, preferisco abbondare. :wink:

2 Mi Piace

ok seguo prima il tuo consiglio, poi nel caso faccio qualche ricerca :+1:

funziona funziona perfettamente

:+1:

Emilio con la parola cast cosa intendi di preciso?
se mi dicevi che bastava solo convertire, io sarei andato a cercare ToConvert
e cose simili, infatti anche la sintassi per come hai convertito ArrayList mai vista prima. . .

ps comunque è una bella gatta da pelare
ho aggiunto la riga modificata nel loop
e mi riporta questo problema:

lo fa su entrambe le righe sia del secondo for che con la riga all’interno di esso
mi dice proprio impossibile eseguire il cast. . .

inizialmente avevo messo un numero a caso 4

for (int col = 0; col < ((ArrayList)(arrList[4])).Count; col++)

e in quel caso il messaggio mi compariva alla stringa di codice nel suo corpo

ho provato anche a sostituire il secondo for col foreach ma nulla

forse non’é cosi, ma penso che il problema sia sul .Count. . .

Prova a vedere qui

secondo caso: conversioni esplicite

In parole povere serve per convertire un valore da un tipo ad un altro tipo.
Ma la cosa deve avere senso, perche’ se no si genera un errore.
Ad esempio puoi convertire un intero in un dobule, ma non in una stringa.
In questo caso e’ ancora un po’ diverso.
Piu’ che convertire direi ‘considerare’, dato che quel valore e’ u effetti una ArrayList, ma e’ visto dal C# come un Object … per motivi di sintassi o altro … :confused:

Nel nostro caso, ArrayList puo’ contenere dati diversi, ma il C# li considera tutti Object.
Non so spiegarti bene come funziona, so solo che quando prendi un valore dalla ArrayList serve il cast.

Credo c’entri questo:

Ma secondo me e’ meglio chiedere a Sergio. :slight_smile:

Spero che il corso di C# parli anche di questo.

Parla di stringa
Se non sbaglio nella ArrayList principale ci sono anche delle stringhe … in pratica ci hai messo di tutto. :smile:
Il cast in ArrayList funziona se l’elemento in questione e’ una ArrayList.
Se e’ un’altra cosa ovviamente non funziona.
Se la ArrayList principale e’ sempre quella che hai scritto all’inizio, i primi 3 valori NON sono delle ArrayList e certo non puoi dire al C#i che sono delle ArrayList senza che lui … ti mandi a quel paese. :smile:

E che senso ha ? :confused:

A parte che dirgli di prendere il Count di una stringa … o di un intero o booleano … :roll_eyes:
Comunque ti ha detto chiaramente che il problema e’ il cast.
Che gli hai detto di trasformare una stringa in una ArrayList … e lui guarda caso si rifiuta.
:wink:

era quello lo scopo

in C# a differenza di Py o VBS bisogna tipizzarli gli Array, gli unici Array che consentono un contenuto misto (di genere) sono proprio gli ArrayList con gli altri tipi di Array invece questo non’é possibile farlo neanche con le liste. quindi lo scopo era creare un ArrayList con i 3 valori principali stringa numero e bool da poter iterare.

appunto avevo detto che il problema era proprio questo, il fatto che se all’interno di un ArrayList, ci sono oggetti vari misti il Count può andar bene per uno ma non per l’altro per questo è una bella gatta da pelare

essendo che si era parlato che gli output degli ArrayList erano tutti oggetti, e mettendo nel
foreach sia var che object non davano errori ho pensato che potesse gestire lui il tutto :grin:
(ci ho provato)

            for (int row = 0; row < arrList.Count; row++)
            {
                for (int col = 0; col < Convert.ToString(arrList[row]).Length; col++)
                {
                    Console.WriteLine(Convert.ToString(arrList[row])[col]);
                }
            }

giocando con le stringhe in questo modo si riesce ad ottenere qualcosa
ma non so se si riesce ad avere il risultato corretto
però anche se fosse il ritorno sarebbero sempre tutti oggetti convertiti in stringa
e si andrebbe a perdere l’obiettivo iniziale di iterare un ArrayList con oggetti misti

ps (e meglio che vada, ormai sono cotto)

edit:
ma vuoi vedere che va a finire come avevo immaginato sin dall’inizio:

con incapsulare gli ArrayList, intendevo che per ogni elemento bisognerebbe fare una verifica per poi prima di iterarlo convertirlo nell’oggetto corretto e di conseguenza usare la proprietà idonea per ognuna di essa.
(un bel lavoraccio. . .)

Se ho capito, stai cercando un modo per iterare su tutti gli oggetti contenuti in una ArrayList, compresi quelli annidati dentro altre ArrayList.
( Credo che di solito lo chiamino flatten )

Se e’ cosi’ … intanto potevi anche dirlo, cosi’ magari chi ti risponde sa di cosa stai parlando.

Poi quello che non trovi gia’ pronto te lo fai.
E’ piuttosto semplice scrivere una funzione che genera la lista di tutti i valori scalari presenti dentro una ArrayList.

Forse possono servire anche gli iteratori, ma non li conosco.
Se ti interessa provo poi a lndagare …

E forse c’e’ ancora altro, forse qualche strumento per la programmazione funzionale … non saprei. :thinking:

Ecco che mi iniziano a girare … e usare una classe (oppure una struct)!!! Almeno i fondamentali …

class Persona{
    public string nome;
    public string cognome;
    public int eta;

    public Persona (){
        nome="Indefinito";
        cognome="Indefinito";
        eta=-1;
    }
        
    public Persona(string _nome,string _cognome,int _eta){
        nome=_nome;
        cognome =_cognome;
        eta=_eta;
    }

    public void printMe(){
        Console.WriteLine( "Nome: " + nome + " Cognome: " + cognome + " età: " + eta);
    }
}


namespace Prova
{
    public class Program
    {
        public static void Main(string[] args)
        {
            List<Persona> gruppo = new List<Persona>();
            
            // metodo 1 di inserimento
            Persona p = new Persona();
            p.nome = "Mario";
            p.cognome="Rossi";
            p.eta=12;
            gruppo.Add(p);
            
            //metodo 2 - più sintetico
            gruppo.Add(new Persona("Guido","La Barca",23));
                       
            for (int i=0; i<gruppo.Count(); i++) {gruppo[i].printMe();}
                           
            Console.WriteLine("Programma terminato");
        }
    }
}

… da consumare sette camicie …

namespace Prova
{
    public class Program
    {
        public static void Main(string[] args)
        {
            List<ArrayList> gruppo =new List<ArrayList>();
            gruppo.Add(new ArrayList(){"Mario","Rossi",12});
            gruppo.Add(new ArrayList(){"Guido","La Barca",23});
 
            for (int i=0; i<gruppo.Count(); i++) {
                ArrayList ArrL =gruppo[i];
                Console.WriteLine( "Nome: " + ArrL[0] + " Cognome: " + ArrL[1] + " età: " + ArrL[2]);
            }
                        
            Console.WriteLine("Programma terminato");
        }
    }
}
1 Mi Piace

:rofl:

Non dovrebbero essere private?

Si.

… anche no! :joy:

Lo so che anche no… Ma si é più meglio no?, :crazy_face:

Graaaandeeeeee Sergignooo gioca bene :wink:

ecco perché la List riporta i segni mag/min può inglobare anche le ArrayList
ottimo, questa soluzione non la conoscevo. buono a sapersi sei mitico :+1:

        static void Main(string[] args)
        {
            List<ArrayList> grp = new List<ArrayList>();
            grp.Add(new ArrayList() { "Mateo" });
            grp.Add(new ArrayList() { "Marco", 10 });
            grp.Add(new ArrayList() { "Luca", 20, null });

            for (int row = 0; row < grp.Count(); row++)
            {
                string nominativo = "";
                for (int col = 0; col < grp[row].Count; col++)
                {
                    Console.WriteLine(grp[row][col]);
                    nominativo += $"{grp[row][col]} ";
                }
                Console.WriteLine(nominativo.Substring(0, nominativo.Length - 1));
            }
            Console.WriteLine("Programma Terminato");

            Console.ReadKey();
        }

la mia idea del codice era orientata ad una cosa simile con lunghezza delle sottoliste differenti. mi interessava capire come ottenere ciò, per il resto ho seguito il consiglio di voi esperti di aspettare prima di cimentarmi con le classi ecc quindi sto facendo pratica su altri aspetti. anzi se potresti dare una breve descrizione della prima parte del codice che hai postato sarebbe molto utile per capire cosa fa il codice :people_hugging:

ps anzi dovrò modificarlo, perché se un valore è null non deve esserci lo spazio vuoto