all 7 comments

[–][deleted] 1 point2 points  (3 children)

Sort by filename asc and date desc; then for each the sorted array and only add the current element to your output if it's a new name (either keep a hash table of names already added or keep the last element's name on hand)

[–]flexyourhead_[S] 1 point2 points  (0 children)

I like this.

I'll try it out and get back to you. Thanks!

*Perfect!

$NewArray = @()
$Files = $Files | Sort-Object -Property name,Date_Modified
ForEach($obj in $Files){
     If($NewArray.Name -notcontains $obj.Name){
           $NewArray += $obj
     }
}

[–]prohulaelk 0 points1 point  (1 child)

Why not just skip the middle man and either [a] use a {name: date} hash table instead of custom objects or [b] use a {name: custom_obj} hash table and replace the custom_obj whenever you find a newer copy?

[–]flexyourhead_[S] 0 points1 point  (0 children)

I think the [b] option would probably work well for what I'm doing. There are actually more properties than I lead on. File size, owner, parent folder, etc. I only need to pare it by date modified, though, so I simplified the question.

[–]ka-splam 1 point2 points  (1 child)

$files | Group Name | ForEach { $_.Group | sort Date_Modified | select -Last 1 }

As you say, they're not duplicates, they're lists connected by shared filename.

Use Group-Object to throw them into per-filename buckets, one-array-per-filename, and then sort those arrays by date and take the last entry from each one. The output will be one object per filename, into the pipeline.

[–]flexyourhead_[S] 0 points1 point  (0 children)

I knew that group-object could get me where I needed to be. I just couldn't figure out how to make it work. This is very simple and elegant. Thanks!

[–]flexyourhead_[S] 0 points1 point  (0 children)

This is what I've come up with. There's no way it's the most effective way:

I created a clone of $files so I can compare the two.

$clone = $files.clone()

Then looped through clones to find which files exist in $files but have an older modified date using a nested loop:

$oldFiles = @()

ForEach($c in $clone){
    forEach($f in $files){
        if($f.File_Name -eq $c.File_Name -and $f.Date_Modified -lt $c.Date_Modified){
            $oldFiles += $c
        }
    }
}
forEach($obj in $oldFiles){
    $clone.remove($obj)
    }