Benutzer mit den meisten Antworten
Zwei gruppierte Objekte (mit Count) zusammenführen

Frage
-
Hallo an diesen warmen Sonnertag,
erneut habe ich mal wieder ein Problem, welches, wie ich mir doch vorstelle, für euch kein Problem darstellt, für mich aber dennoch unlösbar erscheint!
Der Titel der Frage scheint etwas merkwürdig (ich wüsste nicht, wie ich mich besser ausdrucken soll), aber wie so oft kann ein Beispiel alles näher bringen!
Okay, gehen wir mal von einer Textdatei "complete" aus, die wie folgt aussieht:
Klaus Gabi Klaus Klaus Steffan Gabi
In Gruppen sieht das so aus (sprich: gc complete.txt | group | select-object -property Name,count)
Name Count ---- ----- Klaus 3 Gabi 2 Steffan 1
So, jetzt haben wir noch eine zweite Textdatei ("today") die ohne Gruppen so aussieht:
Klaus Klaus Steffan Harald
Und nach Group so aussieht (sprich gc today.txt | group | select-object -property Name,count)
Name Count ---- ----- Klaus 2 Steffan 1 Harald 1
So, ich denke soweit ist alles noch klar.
Wie kann ich diese beiden ("gegroupten" / sortierten) Textdateien zusammenführen, sodass der Count addiert wird (z.B. für Klaus 5).
So sollte das aussehen:
Name Count ---- ----- Klaus 5 Gabi 2 Steffan 2 Harald 1
Habe schon einiges nachgeforscht, aber für mein Problem noch nichts gefunden (oder ich war zu blöd, es darauf anzuwenden).
Ich danke schonmal vielmals und noch einen schönen (ja, sowas gibt es wieder in Deutschland) Sommertag!
Konstantin.
Antworten
-
Hallo,
den Ansatz würde ich auch verfolgen, nur die ForEach-Schleift in Deinem Beispiel würde ich auf jeden Fall austauschen. Wenn man zwei Dateien mit relativ wenigen Datensätzen hat, ist die Methode zu tolerieren. Jedoch ab 5000 Einträgen dauert die Methode wesentlich länger. Die Erweiterung eines Arrays über den += Operator ist extrem teuer, weil die vorhandenen Daten jedes Mal an eine neue Adresse kopiert werden müssen.
Das folgende Script macht einen zeitlichen Vergleich zwischen ca. 10.000x ForEach mit += und nur einmal einem +=.
PS C:\Users\raandree\Dropbox\Desktop> .\join.ps1
Sample 1: 00:03:15.6926225
Sample 2: 00:00:34.4350512$start = Get-Date $a = gc e:\names1.txt $b = gc e:\names2.txt $joinedObject = $a foreach ($name in $b) { $joinedObject += $name} $joinedObject | group | select-object -property Name,count $end = Get-Date "Sample 1: $($end - $start)" $start = Get-Date $joinedObject = gc e:\names1.txt $joinedObject += gc e:\names2.txt $joinedObject | group | select-object -property Name,count $end = Get-Date "Sample 2: $($end - $start)"
-Raimund
- Als Antwort markiert Denniver ReiningMVP, Moderator Donnerstag, 23. August 2012 08:50
-
Du hast recht. Es muß wohl am Wetter liegen, so gehts auch: :)
$start = get-date $a = gc d:\names1.txt $b = gc d:\names2.txt $joinedObject = $a + $b $joinedObject | group | select-object -property Name,count "Seconds: $(((get-date)-$start).totalseconds)"
Grüße, Denniver
Blog: http://bytecookie.wordpress.com
Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".- Bearbeitet Denniver ReiningMVP, Moderator Montag, 20. August 2012 17:22
- Als Antwort markiert Denniver ReiningMVP, Moderator Donnerstag, 23. August 2012 08:50
Alle Antworten
-
Am einfachsten wird es sein, ein gemeinsames Object zu erstellen und dies dann auszuwerten (gruppieren etc):
$a = gc d:\1.txt $b = gc d:\2.txt $joinedObject = $a foreach ($name in $b) { $joinedObject += $name} $joinedObject | group | select-object -property Name,count
Falls du komplexere Dateien (und damit Objekte) hast, gehts nicht ganz so einfach, geht aber auch. Schau mal hier: LINK
Grüße, Denniver
Blog: http://bytecookie.wordpress.com
Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".
- Bearbeitet Denniver ReiningMVP, Moderator Freitag, 17. August 2012 15:50
-
Hallo,
den Ansatz würde ich auch verfolgen, nur die ForEach-Schleift in Deinem Beispiel würde ich auf jeden Fall austauschen. Wenn man zwei Dateien mit relativ wenigen Datensätzen hat, ist die Methode zu tolerieren. Jedoch ab 5000 Einträgen dauert die Methode wesentlich länger. Die Erweiterung eines Arrays über den += Operator ist extrem teuer, weil die vorhandenen Daten jedes Mal an eine neue Adresse kopiert werden müssen.
Das folgende Script macht einen zeitlichen Vergleich zwischen ca. 10.000x ForEach mit += und nur einmal einem +=.
PS C:\Users\raandree\Dropbox\Desktop> .\join.ps1
Sample 1: 00:03:15.6926225
Sample 2: 00:00:34.4350512$start = Get-Date $a = gc e:\names1.txt $b = gc e:\names2.txt $joinedObject = $a foreach ($name in $b) { $joinedObject += $name} $joinedObject | group | select-object -property Name,count $end = Get-Date "Sample 1: $($end - $start)" $start = Get-Date $joinedObject = gc e:\names1.txt $joinedObject += gc e:\names2.txt $joinedObject | group | select-object -property Name,count $end = Get-Date "Sample 2: $($end - $start)"
-Raimund
- Als Antwort markiert Denniver ReiningMVP, Moderator Donnerstag, 23. August 2012 08:50
-
Du hast recht. Es muß wohl am Wetter liegen, so gehts auch: :)
$start = get-date $a = gc d:\names1.txt $b = gc d:\names2.txt $joinedObject = $a + $b $joinedObject | group | select-object -property Name,count "Seconds: $(((get-date)-$start).totalseconds)"
Grüße, Denniver
Blog: http://bytecookie.wordpress.com
Hilf mit und markiere hilfreiche Beiträge als "Hilfreich" und Beiträge die deine Frage ganz oder teilweise beantwortet haben als "Antwort".- Bearbeitet Denniver ReiningMVP, Moderator Montag, 20. August 2012 17:22
- Als Antwort markiert Denniver ReiningMVP, Moderator Donnerstag, 23. August 2012 08:50