Compare an element of an array with the previous element in PowerShell
Solution 1
To compare the current entry to the previous one:
$preventry = ""
$newarray = $()
foreach ($entry in $entries) {
if ($entry -ne $preventry) { $newarray += @($entry) }
$preventry = $entry
}
The resulting array $newarray
contains all the contents of $entries
but with the adjacent duplicates removed.
Solution 2
Select-Object is your friend for this sort of task.
Here's how you can eliminate any duplicates from a collection of strings:
[123] PS↑ C:\> 'a','b','b','c','d','e','e','f','g' | Select-Object -Unique
a
b
c
d
e
f
g
If you're working with objects with multiple properties though, that won't be very helpful if the string representation of the object is the same for every object (e.g. Get-Service | Select-Object -Unique returns one object because all service objects convert to System.ServiceProcess.ServiceController when converted to a string, which cannot be used to uniquely identify a service). In cases like that you need to specify which property you want to check for uniqueness.
Here's another example, that shows you how to get a list of the unique extensions of files in the current directory:
Get-ChildItem | Select-Object -Property Extension -Unique
One of these two techniques should help you get the unique collection you are looking for.
Related videos on Youtube
TZttt
Positive and pragmatic product leader with ten years of experience in B2B and B2C software. Skilled in analyzing the marketplace, synthesizing product vision, and then communicating that vision internally and externally through roadmaps, requirements, and product marketing activities. Seasoned manager of cohesive teams. Strong competencies in research and validation, idea management, prioritization and roadmapping, consensus-building, SDLC process development, product analytics, technical writing, Scrum/Kanban product ownership, and user experience/interface design. I'm passionate about the democratization of content creation and about working with skilled creators and craftspeople of all kinds, including those in media, engineering, software and the arts.
Updated on September 17, 2022Comments
-
TZttt over 1 year
Can someone describe a good pattern to compare $entry[X] to $entry[Y] to determine if they are the same? I'm trying to get readable summaries of my logs and don't want to spit out 400 identical lines.
foreach ($log in $logs) { $nm = $log.LogDisplayName $header = $log.LogDisplayName Write-Host $header Add-Content $output "$header Log Errors/Warnings, Past 48 Hours" $entries = $log.Entries | ? {$_.TimeWritten -gt ($(Get-Date).AddDays(-2)) -and (($_.EntryType -like "Error") -or ($_.EntryType -like "Warning"))} foreach ($entry in $entries) { ***here is where I think I need to compare array elements*** } out-string -inputobject $entries | add-content $output
-
Dennis Williamson over 14 yearsDo you want to check whether each line is unique within the file or whether a line is the same as the previous line?
-
TZttt over 14 yearsJust the previous line. Actually, I probably will want to see if some portion of the lines are the same, but I'll cross that bridge after I figure out how to compare each line with its predecessor in general.
-
-
Dennis Williamson over 14 years$entries = $entries | select-object -unique
-
Dennis Williamson over 14 yearsBy the way, I get a "positional parameter" error because of the sequence of letters at the end of your command.
-
Poshoholic over 14 yearsThe script isn't showing up correctly here. Something to do with the newline character that is being used. The sequence of letters after -Unique should be each on their own line immediately below the command (they are the output of the command).
-
Poshoholic over 14 yearsThere, fixed the output now by moving the command and output into a code block. Thanks for pointing out that it didn't paste correctly.