Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Renault Twingo E-Tech Electric: che prezzo!
Renault Twingo E-Tech Electric: che prezzo!
Renault annuncia la nuova vettura compatta del segmento A, che strizza l'occhio alla tradizione del modello abbinandovi una motorizzazione completamente elettrica e caratteristiche ideali per i tragitti urbani. Renault Twingo E-Tech Electric punta su abitabilità, per una lunghezza di meno di 3,8 metri, abbinata a un prezzo di lancio senza incentivi di 20.000€
Il cuore digitale di F1 a Biggin Hill: l'infrastruttura Lenovo dietro la produzione media
Il cuore digitale di F1 a Biggin Hill: l'infrastruttura Lenovo dietro la produzione media
Nel Formula 1 Technology and Media Centre di Biggin Hill, la velocità delle monoposto si trasforma in dati, immagini e decisioni in tempo reale grazie all’infrastruttura Lenovo che gestisce centinaia di terabyte ogni weekend di gara e collega 820 milioni di spettatori nel mondo
DJI Osmo Mobile 8: lo stabilizzatore per smartphone con tracking multiplo e asta telescopica
DJI Osmo Mobile 8: lo stabilizzatore per smartphone con tracking multiplo e asta telescopica
Il nuovo gimbal mobile DJI evolve il concetto di tracciamento automatico con tre modalità diverse, un modulo multifunzionale con illuminazione integrata e controlli gestuali avanzati. Nel gimbal è anche presente un'asta telescopica da 215 mm con treppiede integrato, per un prodotto completo per content creator di ogni livello
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 16-07-2008, 21:53   #1
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
[LINQ] analisi di matrici

Finora con linq ho lavorato prettamente con dati sequenziali, ma come dovrebbe funzionare in caso di matrici n-dimensionali?
E' possibile utilizzarlo efficacemente o è limitato solo a collection uni-dimensionali?
Ho fatto una rapida prova con una matrice di interi con questo codice:
Codice:
int[][] matrix = {
                             new int[]{1,2,3},
                             new int[]{4,5,6},
                             new int[]{7,8,9}};

            var result = matrix.Select(row => row.Where(value => value > 5));
            foreach (var r in result) r.ForEach(Console.WriteLine);
Che da il risultato voluto, ovvero restituisce i numeri 6, 7, 8 e 9, però ho dovuto usare una Select sulla matrice.
Così facendo in pratica ho ricevuto 3 oggetti Enumerable, mentre ad esempio del primo non saprei che farmene dato che non contiene nessun oggetto maggiore di 5.
Avevo provato inizialmente ad usare un altro Where al posto del Select ma non buildava...
Quale sarebbe quindi la soluzione migliore (se esiste) per lavorare su dati di tipo matriciale con Linq?
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 08:13   #2
cdimauro
Senior Member
 
L'Avatar di cdimauro
 
Iscritto dal: Jan 2002
Città: Germania
Messaggi: 26110
A naso sembra che lavori sempre con dati sequenziali, come anche il tuo esempio dimostra.

Non mi sembra un limite. Tra l'altro finora non m'è mai capitato di lavorare con matrici (omogenee) multidimensionali.
__________________
Per iniziare a programmare c'è solo Python con questo o quest'altro (più avanzato) libro
@LinkedIn Non parlo in alcun modo a nome dell'azienda per la quale lavoro
Ho poco tempo per frequentare il forum; eventualmente, contattatemi in PVT o nel mio sito. Fanboys
cdimauro è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 09:33   #3
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Si', lavora su elementi monodimensionali, ma a tutto c'e' una soluzione.
Ti passo qui 3 modi di risolvere il problema, con l'extension a corredo
Il primo e' piu' simile al tuo, ma con la SelectMany eviti di dover usare un terzo enumeratore.
In pratica la SelectMany e' la UNION ALL dell'SQL, che unisce insieme gli elementi di una sottoenumerazione.

Il secondo fa uso di una Matrice Multidimensionale, con a corredo un AsEnumerable per poter ciclare sugli elementi.
Dovrebbe essere la soluzione migliore per le matrici in C#, dato che rango della matrice e lunghezza di ciascuna dimensione sono fissi e il compilatore lo sa a compile-time.

Il terzo e' di nuovo simile al primo, ma usa una doppia enumerazione creata al volo per accedere ai singoli elementi.
Ovviamente non funziona se la matrice e' atipica (con lunghezza di righe diversa)
In pratica mette in prodotto cartesiano le due enumerazioni, costruendo quindi ogni coppia possibile di X e Y.
Sembra essere la soluzione preferita in caso di computo di grosse moli di lavoro per ciascun elemento, dato che puo' essere resa parallelizzabile semplicemente se al posto della prima Enumerable usi una ParallelEnumerable. Ma non ho fatto studi di fattibilita' in tal senso sugli altri esempi.

Codice:
static class Program
{
    static void Main(string[] args)
    {
        int[][] matrix = {
                         new int[]{1,2,3},
                         new int[]{4,5,6},
                         new int[]{7,8,9}};

        var result = matrix.SelectMany(row => row.Where(value => value > 5));

        result.ForEach(Console.WriteLine);

        Console.ReadKey();
    }


    static void Main2(string[] args)
    {
        int[,] matrix = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };

        var result = matrix.AsEnumerable().Where(t => t > 5);
        result.ForEach(Console.WriteLine);

        Console.ReadKey();
    }

    static void Main3(string[] args)
    {
        int[][] matrix = {
                         new int[]{1,2,3},
                         new int[]{4,5,6},
                         new int[]{7,8,9}};

        int rank = matrix.Rank;
        int dim1 = matrix.Length;
        int dim2 = matrix[0].Length;

        var result = from y in Enumerable.Range(0, dim1)
                     from x in Enumerable.Range(0, dim2)
                     let val= matrix[y][x]
                     where val>5
                     select val;


        result.ForEach(Console.WriteLine);

        Console.ReadKey();
    }

    static IEnumerable<T> AsEnumerable<T>(this T[,] domain)
    {
        foreach (T elem in domain)
            yield return elem;
    }

    static void ForEach<T>(this IEnumerable<T> domain, Action<T> action)
    {
        foreach (T t in domain) action(t);
    }
}
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 10:41   #4
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Piu' interessante potrebbe essere costruire un metodo tipo:

Data una matrice bidimensionale, restituire una matrice bidimensionale di pari geometria, ma con valorizzate solo le celle che soddisfano un determinato filtro.

Es: elemento>5

Con anche il filtro passato come parametro, diverso di volta in volta.
Ho provato, possono venire fuori cose interessanti.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 14:24   #5
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
Il metodo + interessante mi sembra così ad occhio il secondo.
Nel terzo metodo ho scoperto le doppie enumerazioni che ancora non avevo mai visto
ora vedo se riesco a restituire la matrice originale con valorizzati i parametri che soddisfano la condizione espressa nel filtro
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 15:02   #6
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
l'implementazione + semplice che mi è venuta in mente è questa:
Codice:
class Program
    {
        static void Main(string[] args)
        {
            int[][] matrix = {
                             new int[]{1,2,3},
                             new int[]{4,5,6},
                             new int[]{7,8,9}};

            var result = matrix.Select(row => row.Select(value => value > 5 ? value : 0));
            
            foreach (var row in result) 
            {
                foreach (var value in row)
                {
                    Console.Write(value);
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }
ce ne sono di migliori che mi sono sfuggite?
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 15:05   #7
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Il requisito che avevo in mente era una funzione che, dato in ingresso una matrice tipo int [][]
restituisse di nuovo un oggetto matrice, con la stessa geometria, applicando il filtro agli elementi.

Intendo una matrice vera, non solo a video
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
Old 17-07-2008, 15:13   #8
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
Quote:
Originariamente inviato da gugoXX Guarda i messaggi
Il requisito che avevo in mente era una funzione che, dato in ingresso una matrice tipo int [][]
restituisse di nuovo un oggetto matrice, con la stessa geometria, applicando il filtro agli elementi.

Intendo una matrice vera, non solo a video
ah ok
ora non ho tempo che ho chiuso parallels e devo scappare al lavoro
gli do un occhiatina stasera
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 18-07-2008, 00:16   #9
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
non riesco a fare andare il predicate
Codice:
class Program
    {

        static void Main(string[] args)
        {
            int[][] matrix = {
                             new int[]{1,2,3},
                             new int[]{4,5,6},
                             new int[]{7,8,9}};

            int[][] result = matrix.Filter(value => value > 5);   
            
            foreach (int[] row in result) {
                foreach (int value in row)
                {
                    Console.Write(value);
                }
                Console.WriteLine();
            }

            Console.ReadLine();
        }
    }
mi da errore nella riga in bold dicendo:
"Error 1 The type arguments for method 'ProvaLinq.Extensions.Filter<TSource>(int[][], System.Func<int,bool>)' cannot be inferred from the usage. Try specifying the type arguments explicitly. C:\Visual Studio 2008\Projects\ProvaLinq\ProvaLinq\Program.cs 18 30 ProvaLinq"
l'extension method è il seguente:
Codice:
public static int[][] Filter<TSource>(this int[][] matrix, Func<int, bool> predicate)
        {
            return matrix.Select(row => row.Select(value => predicate(value) ? value : 0).ToArray<int>()).ToArray<int[]>();
        }
Ovviamente senza predicate riesco a farla funzionare, ma ancora come utilizzare i delegates durante l'implementazione devo capirlo...
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 18-07-2008, 10:58   #10
^TiGeRShArK^
Senior Member
 
L'Avatar di ^TiGeRShArK^
 
Iscritto dal: Jul 2002
Città: Reggio Calabria -> London
Messaggi: 12112
ce l'ho fatta..
a mente libera ho risolto il problema
Codice:
public static int[][] Filter(this int[][] matrix, Func<int, bool> predicate)
        {
            return matrix.Select(row => row.Select(value => predicate(value) ? value : 0).ToArray<int>()).ToArray<int[]>();
        }
certo che però ancora non ho capito proprio tutto di queste funzioni implementate in questo modo...
__________________
^TiGeRShArK^ è offline   Rispondi citando il messaggio o parte di esso
Old 18-07-2008, 11:38   #11
gugoXX
Senior Member
 
L'Avatar di gugoXX
 
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
Giusto, provo a postare le mie 2 versioni di Generics Extension, che si possono applicare a tutte le matrici bidimensionali.
La sostanza principale era quella di dotare la funzione di un funzionale di filtro (il tuo Func<int,bool>) da poter applciare dinamicamente, e che puo' essere risolto dall'utilizzatore mediante una comodissima lambda function.

Per matrice bidimensionale ho inteso proprio la matrice C# con la sintassi [y,x] e non quella tipica del C e C++ come la [y][x]
Ovvio che si possono portare anche per la versione piu' vecchia.

La prima versione e' iterativa, la seconda e' funzionale.
Per questo caso penso che avrei scelto la iterativa.
Codice:
public static T[,] GetFiltered<T>(this T[,] domain, Func<T, bool> pass)
{            
    int dy = domain.GetLength(0); //0 e 1 sono le dimensioni.
    int dx = domain.GetLength(1);
    T[,] ret = new T[dy, dx];

    for (int y = 0; y < dy; y++)
    {
        for (int x = 0; x < dx; x++)
        {
            T test = domain[y,x];
            ret[y, x] = pass(test) ? test : default(T);
        }
    }
    return ret;
}

public static T[,] GetFiltered2<T>(this T[,] domain, Func<T, bool> pass)
{
    int dy = domain.GetLength(0);
    int dx = domain.GetLength(1);
    T[,] ret = new T[dy, dx];

    var universe = from y in Enumerable.Range(0, dy)
                   from x in Enumerable.Range(0, dx)
                   let test = domain[y, x]
                   let res = pass(test) ? test : default(T)
                   select new {y=y,x=x,res=res};

    universe.ForEach(an => ret[an.y, an.x] = an.res);
    
    return ret;
}

public static void ForEach<T>(this IEnumerable<T> domain, Action<T> action)
{
    foreach (T t in domain) action(t);
}
E l'uso che se ne puo' fare e' p.es.:
Codice:
static void Main(string[] args)
{
    int[,] Mat1 = { { 1, 2, 3 }, { 4, 5, 6 } };
    int[,] Mat1Filt = Mat1.GetFiltered(t => t > 4);

    double[,] Mat2 = { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 } };
    double[,] Mat2Filt = Mat2.GetFiltered2(u => u > 4.5);
}
Tutto fortemente tipizzato e lamentato a compile time se qualche tipo esce fuori dai ranghi.

Ora, sto cercando di capire se e' possibile avere davvero un enumeratore doppio. Intendo, un'enumerazione che abbia alla fine non un sola dimensione ma piu' di una.

L'enumerazione di cui sopra restituisce una serie di oggetti. Ogni oggetto contiene le 2 coordinate (e il risultato del filtro), e su questo ho giocato.
Mi sarebbe invece piaciuto ottenere un'enumerazione doppia, con 2 parametri interi (u,v) invece che uno solo tipizzato (t)

E' una questione di lana caprina, ma mi sarebbe piacuto scrivere qualcosa come la prima, invece che la seconda.
Codice:
universe.ForEach((t, u) => ret[t, u] = qualcosa);

universe.ForEach(an => ret[an.y, an.x] = qualocosa);
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto.
E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test.

Ultima modifica di gugoXX : 18-07-2008 alle 11:46.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Renault Twingo E-Tech Electric: che prezzo! Renault Twingo E-Tech Electric: che prezzo!
Il cuore digitale di F1 a Biggin Hill: l'infrastruttura Lenovo dietro la produzione media Il cuore digitale di F1 a Biggin Hill: l'infrast...
DJI Osmo Mobile 8: lo stabilizzatore per smartphone con tracking multiplo e asta telescopica DJI Osmo Mobile 8: lo stabilizzatore per smartph...
Recensione Pura 80 Pro: HUAWEI torna a stupire con foto spettacolari e ricarica superveloce Recensione Pura 80 Pro: HUAWEI torna a stupire c...
Opera Neon: il browser AI agentico di nuova generazione Opera Neon: il browser AI agentico di nuova gene...
Crolla a 89€ una scopa elettrica low cos...
Anche Huawei segue il trend del mercato:...
Un portatile un tuttofare definitivo a 5...
PosteMobile passerà alla rete TIM...
I 6 migliori smartphone da acquistare su...
iPhone Air 2 è già in cant...
OnePlus 15, in Europa sarà uguale...
Portal X, un nuovo modo per controllare ...
Con Satispay ora si può pagare in...
Sora sbarca anche su Android: una nuova ...
Vibes sbarca in Europa: Meta sfida TikTo...
Tesla, approvato il pacchetto da 1.000 m...
Rockstar posticipa GTA 6 a novembre 2026...
Snap e Perplexity unite: dal prossimo an...
La Cina dice addio a NVIDIA? Il governo ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 08:43.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v