Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Kindle Scribe Colorsoft: riduce le cornici e diventa a colori, ma il prezzo è alto
Kindle Scribe Colorsoft: riduce le cornici e diventa a colori, ma il prezzo è alto
Amazon porta i colori sul suo Kindle da scrittura più grande: schermo Colorsoft a 11 pollici, processore quad-core, penna premium più reattiva e strumenti IA per le note, sono le note salienti. Il salto di prezzo rispetto al modello in bianco e nero si fa sentire, anche se la percezione è quella di trovarsi di fronte a un prodotto di fascia altissima, per veri appassionati
L'IA cambia tutte le regole della sicurezza tra vulnerabilità e sorveglianza. Intervista al CEO di Proofpoint
L'IA cambia tutte le regole della sicurezza tra vulnerabilità e sorveglianza. Intervista al CEO di Proofpoint
Abbiamo intervistato Sumit Dhawan, CEO di Proofpoint, per capire come stia cambiando il mondo della sicurezza con l'avvento dell'intelligenza artificiale e con il ritmo sempre più serrato a cui vengono trovate vulnerabilità nel software. Un problema significativo, che richiederà del tempo per essere risolto (o quantomeno arginato)
L'Europa conta nella tecnologia e può essere autonoma. Cosa si è detto al Nextcloud Summit 2026
L'Europa conta nella tecnologia e può essere autonoma. Cosa si è detto al Nextcloud Summit 2026
La parola d'ordine al Nextcloud Summit 2026, che si è tenuto a Monaco, è stata "sovranità". Non come è spesso usato questo termine in politica ma, al contrario, come capacità positiva di decidere il proprio destino tecnologico, con modalità collaborative e aperte. L'Europa dice già molto nel mondo open source, che viene visto come mezzo per ottenere la tanto agognata autonomia digitale
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 16-07-2008, 20: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, 07: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, 08: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, 09: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, 13: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, 14: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, 14: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, 14: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 17-07-2008, 23: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, 09: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, 10: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 10:46.
gugoXX è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Kindle Scribe Colorsoft: riduce le cornici e diventa a colori, ma il prezzo è alto Kindle Scribe Colorsoft: riduce le cornici e div...
L'IA cambia tutte le regole della sicurezza tra vulnerabilità e sorveglianza. Intervista al CEO di Proofpoint L'IA cambia tutte le regole della sicurezza tra ...
L'Europa conta nella tecnologia e può essere autonoma. Cosa si è detto al Nextcloud Summit 2026 L'Europa conta nella tecnologia e può ess...
Dreame X60 Pro Ultra Complete: i bracci si estendono sempre di più Dreame X60 Pro Ultra Complete: i bracci si esten...
TCL 65C8L, la recensione del SQD-Mini LED da 4400 nit misurati TCL 65C8L, la recensione del SQD-Mini LED da 440...
Koei Tecmo annuncia un nuovo action chia...
La postazione racing di Kimi Antonelli c...
Amazon TOP 10: rivoluzione nelle prime 4...
Amazfit spinge forte su quattro nuovi sm...
Sony esce allo scoperto? In arrivo una P...
Chatbot, salute e dati sanitari: in USA ...
SwitchBot Smart Lock Pro, super sconto e...
LibrePods arriva alla v1.0.0-rc1: il pro...
5 mini PC con 32GB di RAM, da 399€ a 519...
Il futuro è arrotolabile: Samsung punta ...
Meno giochi di terze parti per il futuro...
iOS e iPadOS 26.5.2 ufficiali: quasi 30 ...
macOS Tahoe 26.5.2 rilasciato: nessuna n...
Apple non vuole perdere tempo: i nuovi M...
Motorola Edge 70 Fusion a 284€, prezzo p...
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: 10:59.


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