-
Notifications
You must be signed in to change notification settings - Fork 7.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Select-Object -unique is inconsistently case sensitive #12059
Comments
Odd, I'd assume case sensitivity would only be an issue on non-Windows implementations per the Case-Sensitivity In Powershell known issue. How curious. |
Well, I'm stumped. I looked through the portion of Select-Object code that gets invoked when only the -Unique flag is supplied. I went down every path I could find from the different comparison methods to cultural differences, to type conversion, but everything appears consistently implemented. Aside from the questionable choice to hard-code case-sensitivity into I mean, that would explain why |
It looks like the issue reported is due to not specifying a Property for comparison. Without the Property the comparison is between the base objects of each PSCustomObject which are equal. The Sort-Object cmdlet has a separate switch parameter to set case sensitivity. Updated example showing difference in behavior, note the two Name values in the first example are different words and not just different case. I would agree that it would be nice if this defaulted to compare all properties rather than none but that could be a breaking change.
|
Good catch! Though that behavior is rather alarming as it is both clearly incorrect and an easy mistake for a programmer to make. The help for Select-Object explicitly states that "When you select properties, If that change is judged to be too breaking, we need to update the documentation to make it clear that to select unique objects, the proper syntax is |
So I ran across this issue dealing with REST style API, which doesn't return json or xml objects, just an array of strings. It's similar to what you'd expect from Get-Content on a raw text file. If a property is required for Select-Object to behave as expected, what is one supposed to use to pull uniques out of an array of strings? |
@bobfrankly |
@vexx32 I get that it works, it's listed in original bug report. But what's the design supposed to be? That Select-Object isn't for arrays of strings? Example 4 in the Select-Object appears to state that it's supposed to be used exactly that way. Am I misunderstanding? |
@bobfrankly I would be inclined to assume that, given PowerShell is typically by default case-insensitive, this case is more likely to be a bug than a design choice. |
Just ran into this today. Sort-Object was the workaround, but it is definitely still broken. Pwsh 7.1.3 on Window 10. |
Wow, I had no idea that this sort of a bug was present in Select-Object. In my case, I needed to preserve order and preserve casing from the original addition. My solution uses a case insensitive hashset that will only add to the list IF the input is not present in the list. Good enough for my small lists. (Thanks SeeminglyScience):
|
@Szeraax, you can simplify and improve the performance of your hash-set approach by passing the input collection as an argument to the constructor # -> 'a', 'b'
[Collections.Generic.HashSet[string]]::new([string[]] ("a","A","B","b"), [StringComparer]::OrdinalIgnoreCase) Note, however, that hash sets are documented as unordered, i.e. the output order is not guaranteed to reflect the input order. Unfortunately, there is no built-in .NET type that implements an ordered hash set, as of .NET 6 Thus, if you wanted to preserve the input order, you'd have to something like this (which is considerably slower and more memory-intensive than the solution above): $auxHashSet = [Collections.Generic.HashSet[string]]::new([StringComparer]::OrdinalIgnoreCase)
[array] $distinctInInputOrder = foreach ($str in "a","A","B","b") { if ($auxHashSet.Add($str)) { $str } } |
Wow, that's a really good workaround. Thank you for the additional clarification. 10/10! Now... If we only can get a breaking change approved to fix the bug with select object being case sensitive 😂 |
Glad to hear it was helpful, @Szeraax. If I were to guess, a breaking change is not in the cards (even though conceptually it is undoubtedly called for, along with introducing a |
Ya, that's the frustrating part of working with powershell. The board is so risk averse/change averse that the only hope I have of not dealing with issues like this and other much wanted community fixes (like 1st class support for classes, inline splatting, etc.) is to use something else besides powershell. :( |
@mklement0 I agree including a In the past I have just forced lowercase before piping to C:\> @('A', 'a', 'c').ToLower() | Select-Object -Unique
a
c Which is to work around the unintuitive behaviour we have today. |
@iSazonov What do you think about adding a Curious to see if PowerShell team would be ok with this. |
I personally see no other way but to add the new switch, only Get-Unique should be considered too. |
Steps to reproduce
Expected behavior
Actual behavior
Environment data
The text was updated successfully, but these errors were encountered: