none
Vergleichn von Werten in einem Array mittels Schleife RRS feed

  • Frage

  • Hi,

    ich versuche gerade mittels einer Schleifen ein Feld zu durchlaufen und die Werte zu vergleichen.

    Das Feld ist sortiert und meine Schleife soll das ganze Feld durchlaufen. Entspricht Wert1 = Wert2 greift die erste If-Abfrage, solange sich Werte gleichen soll immer in diese If-Abfrage gesprungen werden. Sind die Werte unterschiedlich greift die zweite If-Abfrage.

    In der Praxis vergleiche ich das ManagedBy Attribut aus einem Active Directory, solange ManagedBy -equal ist werden Daten vom Objekt verarbeitet und in eine Datei geschrieben. Ist das ManagedBy Attribut nicht mehr equal wird die Datei gespeichert und eine neue Datei für den anderen ManagedBy User angelegt. So lange bis alle durchlaufen sind.

    Hier ist mein aktueller Code, ich verstehe jedoch nicht wie ich die Werte vergleichen kann - ich renne hier immer in eine Endlosschleife da ich nicht weiß wie ich den nächsten Wert im Array ansprechen kann.

    $groups= Get-ADGroup -filter{name  -like '*-I-*'} -properties info, member, ManagedBy |select info, member, ManagedBy, DistinguishedName | sort ManagedBy
    
    foreach($group in $groups){
    
    $currentGroup=$group.ManagedBy
    $followingGroup=$group.Managedby[+1]
    
    if ($currentGroup -eq $followingGroup){
    write-host in der if abfrage = Daten Sammeln, usw
    
    }
    
    if ($currentGroup -ne $followingGroup){
    
    write-host New Managed By User, neue Datei anlegen
    }
    
    } 

    Montag, 19. August 2013 10:24

Antworten

  • Hallo,

    nur so zum nachdenken!

    Deine Variable $groups ist im Idealfall eine Array, durch die foreach Schleife hast du dann in $group das akt. Item des Array, das ist dann aber kein Array, also kann das mit dem +1 nicht funktionieren, zudem auch nirgend der Index forstgeschrieben wird usw.

    In diesem englischen Thread geht es zwar um ein anderes Thema, aber da Problem ist das gleiche. Dort findest Du Code von mir, der dir weiterhelfen koennte.

    http://social.technet.microsoft.com/Forums/de-DE/152a5c2b-d308-4136-aa79-af523018149f/isolate-the-top-file-based-on-a-filename-pattern

    auf die schnelle angeappst, ungetestet!

    $groups = @(Get-ADGroup -filter{name  -like '*-I-*'} -properties info, member, ManagedBy |select info, member, ManagedBy, DistinguishedName | sort ManagedBy)
    
    for ($i = 0; $i -lt $($groups.Count - 1);$i++) {
        $currentGroup=$groups[$i].ManagedBy
        $followingGroup=$groups[$i + 1].Managedby
    	if ($currentGroup -eq $followingGroup) {
    		"..."
    	}
        ...
    }



    Beste Gruesse
    brima



    • Als Antwort markiert nehmoht Montag, 19. August 2013 11:02
    • Bearbeitet brima Montag, 19. August 2013 13:53
    Montag, 19. August 2013 10:39

Alle Antworten

  • Der Fehler schein irgendwie an dem [+1] zu liegen. Ich will hier eigentlich ein Element weiter springen.

    Vielen dank für eure Hilfe!

    Montag, 19. August 2013 10:27
  • Hallo,

    nur so zum nachdenken!

    Deine Variable $groups ist im Idealfall eine Array, durch die foreach Schleife hast du dann in $group das akt. Item des Array, das ist dann aber kein Array, also kann das mit dem +1 nicht funktionieren, zudem auch nirgend der Index forstgeschrieben wird usw.

    In diesem englischen Thread geht es zwar um ein anderes Thema, aber da Problem ist das gleiche. Dort findest Du Code von mir, der dir weiterhelfen koennte.

    http://social.technet.microsoft.com/Forums/de-DE/152a5c2b-d308-4136-aa79-af523018149f/isolate-the-top-file-based-on-a-filename-pattern

    auf die schnelle angeappst, ungetestet!

    $groups = @(Get-ADGroup -filter{name  -like '*-I-*'} -properties info, member, ManagedBy |select info, member, ManagedBy, DistinguishedName | sort ManagedBy)
    
    for ($i = 0; $i -lt $($groups.Count - 1);$i++) {
        $currentGroup=$groups[$i].ManagedBy
        $followingGroup=$groups[$i + 1].Managedby
    	if ($currentGroup -eq $followingGroup) {
    		"..."
    	}
        ...
    }



    Beste Gruesse
    brima



    • Als Antwort markiert nehmoht Montag, 19. August 2013 11:02
    • Bearbeitet brima Montag, 19. August 2013 13:53
    Montag, 19. August 2013 10:39
  • Vielen Dank für die Hilfe!

    Ich hab es gerade ähnlich probiert:

    for($i=0; $($groups.Count-1);$i++){
    
    $currentGroup=$groups.ManagedBy[$i]
    $followingGroup=$groups.Managedby[$i+1]
    
    if ($currentGroup -eq $followingGroup){
    write-host in der if abfrage = Daten Sammeln, usw
    
    }
    
    elseif ($currentGroup -ne $followingGroup){
    
    write-host New Managed By User, neue Datei anlegen
    }
    
    } 
    

    Jedoch bleibt diese Variante immer in der ersten If-Abfrage hängen. Die von dir angegebene Variante leider auch. Werte des Feldes sind aber definititv unterschiedlich, habe ich nochmals überprüft.

    Danke!

    Montag, 19. August 2013 10:57
  • Jetzt funktionierst! :-)

    Vielen Dank!

    for ($i = 0; $i -lt $($groups.Count - 1);$i++) {
        $currentGroup=$groups[$i].ManagedBy
        $followingGroup=$groups[$i + 1].Managedby
    	if ($currentGroup -eq $followingGroup) {
    		"equal"
            $currentGroup
            $followingGroup
    	}
        
        if ($currentGroup -ne $followingGroup) {
    		"Not qual"
            $currentGroup
    	}
    
        }

    Montag, 19. August 2013 11:02
  • PowerShell nutz nur sehr einfach Arrays die wenig eigene Methoden haben.
    Hier würde ich dir raten die Klasse Arraylist zu benutzen.
    Dort gibt es eine Methode IndexOf() mit dieser kann man den Index in einem Array abfragen den kannst du dann +1 nehmen.
    Schau dir dort die Methoden an!
    http://msdn.microsoft.com/de-de/library/system.collections.arraylist.aspx

    $CurrentGroup zu benutzen ist Blödsinn! $group ist immer die currrent group!

    # leeres Arraylist Objekt erstellen
    $groups = [System.Collections.ArrayList]@()
    
    $groups.AddRange(@(Get-ADGroup -filter{name  -like '*-I-*'} -properties info, member, ManagedBy |select info, member, ManagedBy, DistinguishedName | sort ManagedBy))
    
    ForEach($group in $groups){
    
    	# index der gruppe im Array ermitteln
    	$indexOfCurrentGroup = $groups.IndexOf($group)
    
    	# Sehen ob wir schon am ende des Arrays angekommen sind
    	If(($indexOfCurrentGroup + 1) -eq $groups.count) {
    	 # wir sind am ende! schleife verlassen
    	 break
    	}
    
    	# folge Gruppe aus dem Array auslesen
    	$followingGroup= $groups[$groups.IndexOf($group) + 1]
    
    	# gruppen vergleichen
    	if ($group -eq $followingGroup){
    		# Gruppen sind gleich
    	    # write-host in der if abfrage = Daten Sammeln, usw
    		Write-Host "Gruppen sind gleich"
    	} Else {
    		# Gruppen sind ungleich
    		Write-Host "Gruppen sind ungleich"
    	}
    } # end ForEach $group


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    • Als Antwort markiert nehmoht Montag, 19. August 2013 11:11
    • Tag als Antwort aufgehoben nehmoht Dienstag, 20. August 2013 08:53
    Montag, 19. August 2013 11:04
  • Super, vielen Dank!

    So ganz hab ich es auch doch noch nicht...

    Eigentlich soll ja solange die Werte gleich sind etwas getan werden, wenn ich mit der if Abfrage arbeite ist er ja direkt wieder raus.

    Ich versuche hinzubekomen, dass solange der Folgewert gleich mit dem aktuellen Wert ist, die Daten gesammelt werden. Erst bei Ungleichheit soll er raus springen und ab der aktuellen Stelle im Array weiter suchen...

    Montag, 19. August 2013 11:11
  • Welche if abfrage meinst du jetzt ?

    Kennst du das Wort Else?

     Wenn Gleich (If) dann mach das, wenn ungleich (Else) dann mach was anderes!

    If() {} Else {} !!!!

    LESEN !!!!!
    http://www.colorconsole.de/PS_Windows/de/about_If.htm


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    Montag, 19. August 2013 11:25
  • Dessen bin ich mir durchaus bewußt...

    Mein Problem ist ja, wie geschrieben: " Ich versuche hinzubekomen, dass solange der Folgewert gleich mit dem aktuellen Wert ist, die Daten gesammelt werden. Erst bei Ungleichheit soll er raus springen und ab der aktuellen Stelle im Array weiter suchen..."

    Montag, 19. August 2013 11:32
  • Hallo,

    im If Zeig willst Du Daten bearteiten, im Else Zweig also bei Manager Wechsel willst Du die Datei schreiben.

    Wenn nun die zweite Gruppe im Array einen anderen Manager wie die erste Gruppe hat wuerden die Daten fuer die erste Gruppe nie in einer Datei landen, usw.

    Da musst Du dir noch ein paar Gedanken machen oder den ganzen Code hier posten, dann wird es einfacher zu helfen.

     
    Beste Gruesse
    brima

    korrigiert Tabelle --> Array (danke Peter)
    • Bearbeitet brima Montag, 19. August 2013 12:23
    Montag, 19. August 2013 11:33
  • @Brima

    Arrays sind keine Tabellen!
    Ein Array ist eine  (einspaltige, eindimensionale) Liste!

    Kleiner, aber in der Informatik, feiner unterschied!

    Arrays mit mehreren dimensionen sind Jagged or Multidimensionale Arrays

    Arrays mit 2 Dimensionen sind Tabellen!

    Array[4][7]

    Arrays mit mehr als 2 Dimensionen sind kompliziert ;-)

    http://www.pavleck.net/powershell-cookbook/ch07.html


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!



    Montag, 19. August 2013 11:58
  • Dessen bin ich mir durchaus bewußt...


    Scheint nicht so! Denn in deinem Eingangspost verwendest du 2 getrennte If Abfragen die genau das machen, wie ein IF{} Else{} !

    Mein Problem ist ja, wie geschrieben: " Ich versuche hinzubekomen, dass solange der Folgewert gleich mit dem aktuellen Wert ist, die Daten gesammelt werden.

    Dies macht die If Abfrage wo die Gruppen übereinstimmen!

     Erst bei Ungleichheit soll er raus springen und ab der aktuellen Stelle im Array weiter suchen..."


    Dies kannst du in dem Else{} Zweig machen. Und dir die Aktuelle Position merken im Array merken! Warte mal ...Ich entwickle gleich mal was.

    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    Montag, 19. August 2013 12:07
  • Hallo Peter,

    :-) die Unterschiede sind mir schon bakannt, aber es passiert mir leider immer wieder das ich anstelle von Array Tabelle schreibe. :-(

    Beste Gruesse
    brima
    Montag, 19. August 2013 12:20
  • Du musst einfach im ELSE{} Zweig einen neuen (eindeutigen) Dateinamen generieren. Der dann den alten ersetzt.

    So müsst es tun (ungetestet)!

    # leeres Arraylist Objekt erstellen
    $groups = [System.Collections.ArrayList]@()
    
    $groups.AddRange(@(Get-ADGroup -filter{name  -like '*-I-*'} -properties info, member, ManagedBy |select info, member, ManagedBy, DistinguishedName | sort ManagedBy))
    
    # variabel zum erstellen der eindeutigen Dateinamen
    $Dateicounter = 0
    
    ForEach($group in $groups){
    
    	# index der gruppe im Array ermitteln
    	$indexOfCurrentGroup = $groups.IndexOf($group)
    
    	# Sehen ob wir schon am ende des Arrays angekommen sind
    	If(($indexOfCurrentGroup + 1) -eq $groups.count) {
    	 # wir sind am ende! schleife verlassen
    	 break
    	}
    
    	# folge Gruppe aus dem Array auslesen
    	$followingGroup= $groups[$groups.IndexOf($group) + 1]
    
    	# gruppen vergleichen
    	if ($group.ManagedBy -eq $followingGroup.ManagedBy){
    		# Gruppen manager sind gleich
    	    # write-host in der if abfrage = Daten Sammeln, usw
    		# Ich erstelle den Dateinamen anhand der GruppeName + Dateicounter"
    		# daten werden angehängt !
    		"Daten" | Out-File ("C:\Temp\{0}{1}.txt" -f $group.Name,$Dateicounter) -append
    		
    	} Else {
    		# Gruppen sind ungleich
    		# Dateicounter hochzählen um eindeutige dateinamen zu generieren
    		$Dateicounter++
    		
    		# Ich erstelle den Dateinamen anhand der GruppeName + Dateicounter"
    		# Datei wird mit daten neu erstellt!
    		"Daten" | Out-File ("C:\Temp\{0}{1}.txt" -f $group.Name,$Dateicounter)
    	}
    	
    } # end ForEach $group


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!

    Montag, 19. August 2013 12:39
  • Hallo Peter,

    ich lerne ja lieber von Dir, wie Kritik an deiner Loesung zu ueben. Deine Loesung hat aber glaube ich den Schoenheitsfehler, dass die Daten der letzten Gruppe in der ArrayList nicht bearbeitet werden.

    Ich habe hier mal ein kleines Beispiel zusammengeschustert:

    Dieses Objekt gebaut:

    $GroupObject = @() $GroupObjectMember = New-Object Object Add-Member -InputObject $GroupObjectMember -MemberType NoteProperty -Name GN -Value GoupA Add-Member -InputObject $GroupObjectMember -MemberType NoteProperty -Name GAtt -Value 2 Add-Member -InputObject $GroupObjectMember -MemberType NoteProperty -Name Manager -Value Man1 $GroupObject += $GroupObjectMember
    $GroupObjectMember = New-Object Object
    Add-Member -InputObject $GroupObjectMember -MemberType NoteProperty -Name GN -Value GoupB
    Add-Member -InputObject $GroupObjectMember -MemberType NoteProperty -Name GAtt -Value 4
    Add-Member -InputObject $GroupObjectMember -MemberType NoteProperty -Name Manager -Value Man1
    $GroupObject += $GroupObjectMember

    # usw.



    GN                                                                         GAtt Manager
    --                                                                         ---- -------
    GoupA                                                                         2 Man1
    GoupB                                                                         4 Man1
    GoupC                                                                         6 Man1
    GoupD                                                                        22 Man2
    GoupE                                                                        44 Man2
    GoupF                                                                        66 Man6

    Daten sammele ich uber das Property Gatt, fuer das ich pro Manager die Summe bilde.

    $Summe = 0
    for ($i = 0; $i -lt $($GroupObject.Count - 1);$i++) {
    	If ($GroupObject[$i].Manager -eq $GroupObject[$i + 1].Manager) {
    		$Summe += $GroupObject[$i].GAtt
    	}
    	else {
    		$Summe += $GroupObject[$i].GAtt
    		"Summe $($GroupObject[$i].Manager): $Summe"
    		$Summe = 0
    		
    	}
    }
    $Summe += $GroupObject[$i].GAtt
    "Summe $($GroupObject[$i].Manager): $Summe"

    Ich erhalte dann folgendes Ergebnis:

    Summe Man1: 12
    Summe Man2: 66
    Summe Man6: 66

    Wenn ich deinen Code nutze, d.h. die Dateierstellung und so durch die Summenbildung ersetze erhale ich nur dieses Ergebnis.

    Summe Man1: 12
    Summe Man2: 66

    Beste Gruesse
    brima


    • Bearbeitet brima Montag, 19. August 2013 13:51
    Montag, 19. August 2013 13:31
  • Deine Loesung hat aber glaube ich den Schoenheitsfehler, dass die Daten der letzten Gruppe in der ArrayList nicht bearbeitet werden.

    Da hast du recht !

    Ich habe leider nicht immer die Zeit gründlich und 100% fehlerfrei zu Antworten.

    Deine Lösung hat aber den schönheitsfehler. Das $i + 1 am ende des Arrays kann ausserhalb des Index liegen. Deshalb nehme ich bei so etwas lieber ForEach(), das neben bei auch noch schneller arbeitet als die For() Schleife.

    Bim im moment im stress und kann keine gute Lösung finden...


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!


    • Bearbeitet Peter Kriegel Montag, 19. August 2013 14:29 fsdffsdfs
    Montag, 19. August 2013 14:29
  • Eh nein, das Array hat 6 Eintraege, also ist der Count 6, die Schleife laueft solange der Wert kleiner (Count - 1) ist, also solange $i < 5,
    also von 0..4, durch das $i + 1 wird beim Lauf mit $i = 4 der Manger gegen den von $i = 5 geprueft, also der mit dem greoessten Index und weil $i nach der Schleife dann den Wert 5 hat wird dieser nach der Schleife korrekt bearbeitet.

    Bei deiner Loesung koennte man z.B.: vor dem Break jenachdem ob der Manager gleich ist oder nicht wie der Manger [-1] ein Schreiben mit/ohne Append einbauen.

    Aber genau diese auf den ersten Blcik einfachen Fragen haben es oft in Sich und machen es schwer 100% Loesungen auf Anhieb zu liefern, aber die Fragenden sollen ja auch noch mitdenken. :-)

    Beste Gruesse
    brima
    • Bearbeitet brima Montag, 19. August 2013 15:37
    Montag, 19. August 2013 15:36
  • @Brima Hast recht deine Lösung ist besser und richtig !


    @shizzefrizz

    Biite nimm den Haken bei meinen Lösungen wieder raus!


    Please click “Mark as Answer” if my post answers your question and click “Vote As Helpful” if my Post helps you.
    Bitte markiere hilfreiche Beiträge von mir als “Als Hilfreich bewerten” und Beiträge die deine Frage ganz oder teilweise beantwortet haben als “Als Antwort markieren”.
    My PowerShell Blog http://www.admin-source.info
    [string](0..21|%{[char][int]([int]("{0:d}" -f 0x28)+('755964655967-86965747271757624-8796158066061').substring(($_*2),2))})-replace' '
    German ? Come to German PowerShell Forum!


    Dienstag, 20. August 2013 05:51