[c#] Selectie maken van list collection - FindAll()

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik wil een selectie uitvoeren op een list collection om zo een subset te selecteren. Ik maak gebruik van de FindAll method (deze accepteert slechts één argument). Ik wil echter het ticket ook kunnen doorgeven naar de Predicate. Voor zover ik kan zien is dit niet mogelijk. Hoe kan ik dit het beste aanpakken?

C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
                long ticket = 2234;
                List<CustomObject> transactions = 
                    dataCollection.FindAll(MatchByTicketOrTranslink);

#####

 private static bool MatchByTicketOrTranslink( CustomObject transaction )
        {
            if ( transaction.Ticket == ticket || transaction.Translink == ticket )
            {
                return true;
            }
            else
            {
                return false;
            }
        }

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Oei, een beroemde constructie van het type "if(a) return true else return false" die je denk ik uit de help hebt. Lelijk van MS :)

Ik zou dit gewoon met Linq/Where oplossen. Dus iets als .Where(c => c.t == t || c.t2 == t).ToList()

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
pedorus schreef op zaterdag 25 oktober 2008 @ 00:10:
Oei, een beroemde constructie van het type "if(a) return true else return false" die je denk ik uit de help hebt. Lelijk van MS :)
Ik snap niet helemaal wat je bedoelt, kun je uitleggen wat er verkeerd aan is?
Ik zou dit gewoon met Linq/Where oplossen. Dus iets als .Where(c => c.t == t || c.t2 == t).ToList()
Ik had al bedacht dat Linq misschien een oplossing zou kunnen zijn, maar dat is .Net 3.5 en ik ben er nog niet echt mee bezig. Ik wil het graag eerst implementeren zonder Linq. Misschien is een delegate maken een goede oplossing?

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Verwijderd schreef op zaterdag 25 oktober 2008 @ 00:17:
Ik snap niet helemaal wat je bedoelt, kun je uitleggen wat er verkeerd aan is?
Niks perse, maar zo'n if is onnodig.
Ik had al bedacht dat Linq misschien een oplossing zou kunnen zijn, maar dat is .Net 3.5 en ik ben er nog niet echt mee bezig. Ik wil het graag eerst implementeren zonder Linq. Misschien is een delegate maken een goede oplossing?
Ik had zelf zo'n soort voorbeeld in de help gezet:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class CustomObjectMatcher
{
    public int ticket { get; set; }

    public bool match(CustomObject c)
    {
        return c.ticket == ticket || c.ticket2 == ticket;
    }

    public CustomObjectMatcher(int ticket)
    {
        this.ticket = ticket;
    }
}

...
     result = list.FindAll(new CustomObjectMatcher(1234).match);

Of gewoon:
C#:
1
z.FindAll(c => c.ticket == 1234 || c.ticket2 == 1234);

Of:
C#:
1
2
3
4
z.FindAll(delegate(CustomObject c)
{
    return c.ticket == 1234 || c.ticket2 == 1234;
});

Maar goed, ik ben een beetje vergeten waar 3.5 is begonnen. Misschien een beetje laat op de dag ;)

[ Voor 14% gewijzigd door pedorus op 25-10-2008 01:09 ]

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik zou het dan eerder zo doen ( Als je de oplossing zonder Linq wil doen )

C#:
1
result = list.FindAll( new delegate( CustomObject c ) { return c.ticket == 1234 || c.ticket2 == 1234; } );

Het is denk een beetje overbodig om er een apart object voor te maken.

[ Voor 15% gewijzigd door Woy op 25-10-2008 10:18 ]

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
rwb schreef op zaterdag 25 oktober 2008 @ 10:18:
Het is denk een beetje overbodig om er een apart object voor te maken.
Het voordeel zou zijn dat dat vanaf C# 1.0 al kon, en je bij de variabele ticket kan blijven komen als je de function scope van de aanroepende functie hebt verlaten. Maar List bestond toen natuurlijk nog niet, dus het is een beetje onzin. :)

Ik heb het nog even opgezocht, en mijn 2e oplossing is de aangeraden oplossing in c# 3.0. Het voordeel van delegate is dat die al vanaf c# 2.0 kan.

In .NET 3.5 is Where erbij gekomen, welke met IEnumerables werkt ipv Lists, zodat je niet steeds de resultaten in een List hoeft te stoppen. Als je echt van een List naar een List gaat kun je natuurlijk gewoon FindAll() gebruiken, maar dat is vaak niet nodig.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

Verwijderd

pedorus schreef op zaterdag 25 oktober 2008 @ 12:12:
Ik heb het nog even opgezocht, en mijn 2e oplossing is de aangeraden oplossing in c# 3.0. Het voordeel van delegate is dat die al vanaf c# 2.0 kan.
Ik neem aan dat je versienummers op 't .NET framework slaan en niet op C#?
Bij klanten mag je al blij zijn dat er .NET 2.0 staat of dat je dat mag installeren (soms ben je beperkt tot 1.1), maar 3.0 of 3.5 is vaak doodgewoon geen optie.
In die gevallen heb je geen LINQ, en moet je 't dus via een delegate oplossen.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Verwijderd schreef op zaterdag 25 oktober 2008 @ 15:26:
Ik neem aan dat je versienummers op 't .NET framework slaan en niet op C#?
De laatste wel, de rest op de compiler (fout bij laatste nu gefixt).
Bij klanten mag je al blij zijn dat er .NET 2.0 staat of dat je dat mag installeren (soms ben je beperkt tot 1.1), maar 3.0 of 3.5 is vaak doodgewoon geen optie.
In die gevallen heb je geen LINQ, en moet je 't dus via een delegate oplossen.
De resulterende binary is hetzelfde, enkel de lambda schrijfwijze is anders en alleen met een c# 3.0 compiler beschikbaar. Voor het klant-verhaal maakt het dus niks uit, zolang je geen Where gebruikt.
Tegenwoordig ondersteund trouwens ook Mono LINQ, dus het gaat wel de goede kant op.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 13:23
Verwijderd schreef op zaterdag 25 oktober 2008 @ 15:26:
[...]
Ik neem aan dat je versienummers op 't .NET framework slaan en niet op C#?
Bij klanten mag je al blij zijn dat er .NET 2.0 staat of dat je dat mag installeren (soms ben je beperkt tot 1.1), maar 3.0 of 3.5 is vaak doodgewoon geen optie.
In die gevallen heb je geen LINQ, en moet je 't dus via een delegate oplossen.
In C# 3.0 (dus niet het framework 3.0; C# 3.0 werkt perfect met .NET 2.0) heb je al lambda expressies. Die 2de oplossing van Pedorus kan dus perfect in C# 3.0 icm .NET 2.0

Dit is gewoon mogelijk in C#3.0 icm .NET 2.0, en je maakt ook geen gebruik van LINQ (logisch, want dat heb je niet in .NET 2.0)
C#:
1
2
3
4
5
6
7
8
List<int> lijstje = new List<int> () { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

List<int> result = lijstje.FindAll (i => i == 2 || i == 3);

foreach( int r in result )
{
    Console.WriteLine (r);
}

[ Voor 22% gewijzigd door whoami op 26-10-2008 10:43 ]

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • EfBe
  • Registratie: Januari 2000
  • Niet online
whoami schreef op zondag 26 oktober 2008 @ 10:40:
[...]

In C# 3.0 (dus niet het framework 3.0; C# 3.0 werkt perfect met .NET 2.0) heb je al lambda expressies. Die 2de oplossing van Pedorus kan dus perfect in C# 3.0 icm .NET 2.0
Correctie, C# 3.0 werkt niet 'perfect' met .NET 2.0. Bv the from ... constructies compileren naar extension methods van IEnumerable die je niet hebt.
Dit is gewoon mogelijk in C#3.0 icm .NET 2.0, en je maakt ook geen gebruik van LINQ (logisch, want dat heb je niet in .NET 2.0)
C#:
1
2
3
4
5
6
7
8
List<int> lijstje = new List<int> () { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

List<int> result = lijstje.FindAll (i => i == 2 || i == 3);

foreach( int r in result )
{
    Console.WriteLine (r);
}
Dus in vs.net 2008: target framework op .NET 2.0 zetten. Let wel dat FindAll() in .NET 2.0 geintroduceerd is, dus mocht je op .NET 1.1 moeten draaien dan werkt dat niet, maar .NET 1.1 is dan ook wel erg oud IMHO.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com

Pagina: 1