[C#] Filteren over meerdere collections

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Creegfire
  • Registratie: Februari 2005
  • Laatst online: 18-09-2024
Hallo allemaal,

Ontwikkelomgeving: Visual Studio 2008
Framework: 3.5

Probleem:

Momenteel ben ik bezig met een klein programma om snel en eenvoudig excel lijsten te vergelijken. Het laden e.d. werkt allemaal zoals het hoort en is ook volledig geimplementeerd. Echter waar ik een probleem heb ondervonden is het vergelijken van deze lijsten.

Mijn denkrichting:

Om mijn probleem duidelijker te maken zal ik proberen uit te leggen hoe ik het programma heb opgebouwd.

De volgende objecten zijn momenteel bekend:

Workbook
Worksheet
Column
Cell

Workbook -> Worksheet -> Column -> Cell (dit is de relatie tussen deze objecten)

Tijdens het laden kan de gebruiker kiezen welke worksheet gebruikt moet worden. Deze worksheet bevat dan de gegevens die vergeleken zullen worden. Na het kiezen worden de kolommen aangemaakt met daarin de cells. Deze cells bevatten dan de waarde die uit excel is gelezen. Deze cells zien er dan als volgt uit:

int _Row = 1;
string _Value = "MijnValue";

Per kolom zullen deze cells aangemaakt worden waardoor de volgende situatie ontstaat:

Kolom 1 - Kolom 2 - Kolom 3
Cell 1 - Cell 2 - Cell 3
Cell 1 - Cell 2 - Cell 3

Er zijn drie objecten van kolom waarin een collection van cells zitten.

Mijn vraag:

Ik wil gaan zoeken per cell en niet over de volledige regel, maar toch moet hij iedere kolom filteren (klinkt misschien raar maar ik ga het proberen uit te leggen).

Ik geef Cell1 door met de waarde bijvoorbeeld: "MijnWaarde". Deze moet hij in kolom1 filteren maar deze filtering moet ook doorgegeven worden aan kolom2 en kolom3. Dan komt mijn volgende waarde binnen van Cell2 "MijnWaarde2". Deze moet hij dan in kolom1, kolom2 en kolom3 filteren. Zodoende volgt dus ook de derde waarde die hij overal moet filteren. Waardoor ik één regel of geen regel als resultaat overhou.

Ik hoop dat jullie me een richting of oplossing kunnen geven voor mijn probleem.

Al onderzocht:

Ik heb al geprobeerd op google te zoeken maar helaas heb ik geen resultaten gevonden. Ik wist ook niet concreet waarop ik moest zoeken.

Mijn zoekopdrachten:

C# Findall, Multiple Collections
C# Filtering Multiple Collections
.NET Filtering Multiple Collections
.NET List FindAll Multiple
C# Filtering Lists
etc.. (alle zoekopdrachten komen hierin de buurt)


Ik hoop dat jullie me kunnen helpen en dat mijn verhaal duidelijk overkomt. Als er iets niet duidelijk is probeer ik dit nog zo duidelijk mogelijk toe te lichten.

//Creegfire


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Ik snap er eigenlijk weinig van. Geef eens een voorbeeldje van de data die je hebt, wat je daar voor filter overheen wilt doen, en wat het resultaat dan moet zijn.

Verder denk ik dat je te moeilijk denkt, ga gewoon eens op papier zetten hoe je dit handmatig aan zou pakken. Dus je print je excel sheet uit op papier, en je wil wat gaan filteren. Probeer dan eens een voor een de stappen die je daar in je hoofd voor doet op te schrijven.

“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!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 20:58

Guldan

Thee-Nerd

Volgens wordt er bedoeld dat hij voor iedere kolom een lijst heeft. En nadat hij 1 op een bepaalde manier sorteerd de anderen ook meegaan? Of bedoel echt filteren? Dan zou je de lijsten een gelijke index kunnen geven en bij een filter alleen de rijen laten zien die in de eerste collectie zitten.

Of je zou voor iedere cel de Icomparable interface kunnen implementeren om de cellen te vergelijken.

[ Voor 14% gewijzigd door Guldan op 23-12-2009 22:08 ]

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 13-09 21:30
Gebruik een UltraWinGrid daar zit die filterfunctionaliteit standaard ingebakken ;)

  • Compuhair
  • Registratie: September 2009
  • Laatst online: 23:26
Volgens mij bedoelt hij zoiets:

code:
1
2
3
4
5
6
7
8
9
10
Kolom1    Kolom2   Kolom3
-------   -------  -----
Appels    Groen    Jona Gold
Appels    Groen    Granny Smith
Appels    Rood     Red Star
Peren     Groen    Eetbare peer
Peren     Bruin    Bedorven peer
Citroen   Geel     Spaanse citroen
Citroen   Groen    Dit is eigenlijk een komkommer
....      ...      ...


Als je dan voor kolom1 de filterwaarde 'Appels' instelt, dan hou je deze lijst over:

code:
1
2
3
4
5
Appels    Kolom2   Kolom3
-------   -------  -----
Appels    Groen    Jona Gold
Appels    Groen    Granny Smith
Appels    Rood     Red Star


En als je dan in kolom2 de filterwaarde groen instelt, dan is dit het eindresultaat:

code:
1
2
3
4
Appels    Groen    Kolom3
-------   -------  -----
Appels    Groen    Jona Gold
Appels    Groen    Granny Smith



Dit bedoel je toch, of niet?

  • Mastermind
  • Registratie: Februari 2000
  • Laatst online: 13-09 21:30
Dat denk ik ook ja.
Deze control is wat je nodig hebt:
http://www.infragistics.c...rms/wingrid.aspx#Overview

  • Creegfire
  • Registratie: Februari 2005
  • Laatst online: 18-09-2024
Sorry voor mijn late reactie...

Maar het klopt hoe je de situatie omschrijft. Ik wou al proberen om zon voorbeeld te maken maar helaas weet ik niet hoe ik dat fatsoenlijk hier in Tweakers.net kan doen. Alvast bedankt ervoor.

Ik ga eens kijken! naar de oplossingen die jullie hebben geboden. Alvast bedankt iedereen voor het reageren! :).

*EDIT*

Die winforms producten moeten gekocht worden of zijn deze ook gratis te downloaden?

[ Voor 12% gewijzigd door Creegfire op 24-12-2009 16:06 . Reden: Vraag ]

//Creegfire


  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Als elke cell in de kolommen een row-integer heeft, dan is het toch ook vrij eenvoudig om die filtering gewoon zelf te doen?

Je houdt een lijstje bij van rows die er zijn, en gooit voor elke kolom die je filtert de rows weg. In java-pseudo code (ik ken C# niet goed genoeg) is dat zoiets:
Java:
1
2
3
4
5
6
7
8
9
10
boolean[] rowvisibles = new boolean[rowCount];
Arrays.fill(rowvisibles, true);
for(Column colum : columns)
{
  for(Cell cell : colums.getCells())
  {
     if(rowvisibles[cell.getRowPointer()] && !someFilter(cell))
       rowvisibles[cell.getRowPointer()] = false;
  }
}


En dan kan je, imho, vrij eenvoudig de boel filteren. Of je het een mooie oplossing is moet je natuurlijk zelf weten :P Achteraf moet je dan nog ervoor zorgen dat de rijen uiteindelijk allemaal onzichtbaar worden of wat je doel ook precies is.

Je zou natuurlijk ook je model kunnen omzetten in een row-based model, mits dat met de door jou gebruikte componenten e.d. bruikbaar is. Dan kan je iig efficienter itereren.

  • Alex
  • Registratie: Juli 2001
  • Laatst online: 20-08 21:38
@ACM, Microsoft maakt het op bovenstaande manier PowerPivot(voormalig Project Gemini) aan het werk voor Excel.
Het filtreren van miljoenen rijen in memory. Zie: http://powerpivot.com/
En http://channel9.msdn.com/...ss-Inside-Project-Gemini/

Deze post is bestemd voor hen die een tegenwoordige tijd kunnen onderscheiden van een toekomstige halfvoorwaardelijke bepaalde subinverte plagiale aanvoegend intentioneel verleden tijd.
- Giphart


  • DutchCommando
  • Registratie: November 2000
  • Laatst online: 22:35
Je kan ook aan de class die een row representeert (als dit het geval is) een methode toevoegen die een Func<bool> accepteert. Waarbij deze functie je filter representeert. Vervolgens voeg je aan de class een IsVisible Property toe, welke de doorgegeven functie gebruikt om te bepalen of het object zichtbaar is.

Acties:
  • 0 Henk 'm!

  • Mysteryman
  • Registratie: Februari 2001
  • Laatst online: 22:14

Mysteryman

kan jij wat ik kan...

Het is misschien wat overkill, maar ik gebruik objectlistview om soortgelijke functionaliteit te maken in een applicatie waar ik nu mee bezig ben.

In Objectlistview is iedere regel/item een object, en dat is wat wennen, maar werkt perfect!

Voorbeeldje:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void Filter(string zoekwoord) {
            // maak een nieuwe tijdelijke lijst aan met dezelfde items die je nu al hebt
            List<Objecten> nieuweLijst = new List<Objecten>();

            // Loop door alle bestaande objecten heen en kopieer deze in de nieuwe lijst
            foreach (Object o in ObjectListView.Objects)
            {
                nieuweLijst.Add(o);
            }

            // Loop door de nieuwe lijst heen
            foreach (Object o in nieuweLijst)
            {
                // Als het object niet voldoet aan mijn zoekterk/filter
                if (!o.ToLower().Contains(zoekwoord))
                {
                    // Haal het object weg uit mijn originele verzameling
                    ObjectListView.RemoveObject(t);
                }
            }
}


Het voordeel hiervan is dat je nu * keer kan filteren door gewoon iedere keer de objecten te pakken die nu in de lijst staan.

Het ziet er wat ranzig uit misschien, maar dit is ook maar mijn eerste ervaring met C# :)

[ Voor 5% gewijzigd door Mysteryman op 25-12-2009 13:10 ]

Everybody happy??? I soon change that here we go...


Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Mysteryman schreef op vrijdag 25 december 2009 @ 12:28:
Het is misschien wat overkill, maar ik gebruik objectlistview om soortgelijke functionaliteit te maken in een applicatie waar ik nu mee bezig ben.

In Objectlistview is iedere regel/item een object, en dat is wat wennen, maar werkt perfect!

Voorbeeldje:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
private void Filter(string zoekwoord) {
            // maak een nieuwe tijdelijke lijst aan met dezelfde items die je nu al hebt
            List<Objecten> nieuweLijst = new List<Objecten>();

            // Loop door alle bestaande objecten heen en kopieer deze in de nieuwe lijst
            foreach (Object o in ObjectListView.Objects)
            {
                nieuweLijst.Add(o);
            }

            // Loop door de nieuwe lijst heen
            foreach (Object o in nieuweLijst)
            {
                // Als het object niet voldoet aan mijn zoekterk/filter
                if (!o.ToLower().Contains(zoekwoord))
                {
                    // Haal het object weg uit mijn originele verzameling
                    ObjectListView.RemoveObject(t);
                }
            }
}


Het voordeel hiervan is dat je nu * keer kan filteren door gewoon iedere keer de objecten te pakken die nu in de lijst staan.

Het ziet er wat ranzig uit misschien, maar dit is ook maar mijn eerste ervaring met C# :)
Die code kan een stuk efficienter door alleen items aan de lijst toe te voegen als ze wel voldoen aan je criteria, en alle andere in de list null laat.

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max

Pagina: 1