mirror of
https://github.com/PowerShell/PowerShell
synced 2026-06-08 12:12:50 +00:00
Add '-SkipIndex' parameter to 'Select-Object' (#7483)
This commit is contained in:
committed by
Dongbo Wang
parent
791159d615
commit
618d9f31a0
@@ -161,7 +161,7 @@ namespace Microsoft.PowerShell.Commands
|
||||
public SwitchParameter Wait { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Used to display the object at specified index.
|
||||
/// Used to display the object at the specified index.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
[Parameter(ParameterSetName = "IndexParameter")]
|
||||
@@ -177,11 +177,36 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
_index = value;
|
||||
_indexSpecified = true;
|
||||
_isIncludeIndex = true;
|
||||
Array.Sort(_index);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to display all objects at the specified indices.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
[Parameter(ParameterSetName = "SkipIndexParameter")]
|
||||
[ValidateRangeAttribute(0, int.MaxValue)]
|
||||
[SuppressMessage("Microsoft.Performance", "CA1819:PropertiesShouldNotReturnArrays")]
|
||||
public int[] SkipIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
return _index;
|
||||
}
|
||||
set
|
||||
{
|
||||
_index = value;
|
||||
_indexSpecified = true;
|
||||
_isIncludeIndex = false;
|
||||
Array.Sort(_index);
|
||||
}
|
||||
}
|
||||
|
||||
private int[] _index;
|
||||
private bool _indexSpecified;
|
||||
private bool _isIncludeIndex;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -641,15 +666,18 @@ namespace Microsoft.PowerShell.Commands
|
||||
_selectObjectQueue = new SelectObjectQueue(_first, _last, Skip, SkipLast, _firstOrLastSpecified);
|
||||
}
|
||||
|
||||
private int _indexOfCurrentObject = 0;
|
||||
private int _indexCount = 0;
|
||||
/// <summary>
|
||||
/// Handles processing of InputObject.
|
||||
/// </summary>
|
||||
protected override void ProcessRecord()
|
||||
{
|
||||
if (InputObject != AutomationNull.Value && InputObject != null)
|
||||
{
|
||||
if (!_indexSpecified)
|
||||
if (_indexSpecified)
|
||||
{
|
||||
ProcessIndexed();
|
||||
}
|
||||
else
|
||||
{
|
||||
_selectObjectQueue.Enqueue(InputObject);
|
||||
PSObject streamingInputObject = _selectObjectQueue.StreamingDequeue();
|
||||
@@ -657,39 +685,82 @@ namespace Microsoft.PowerShell.Commands
|
||||
{
|
||||
ProcessObjectAndHandleErrors(streamingInputObject);
|
||||
}
|
||||
|
||||
if (_selectObjectQueue.AllRequestedObjectsProcessed && !this.Wait)
|
||||
{
|
||||
this.EndProcessing();
|
||||
throw new StopUpstreamCommandsException(this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_indexOfCurrentObject < _index.Length)
|
||||
{
|
||||
int currentlyRequestedIndex = _index[_indexOfCurrentObject];
|
||||
if (_indexCount == currentlyRequestedIndex)
|
||||
{
|
||||
ProcessObjectAndHandleErrors(InputObject);
|
||||
while ((_indexOfCurrentObject < _index.Length) && (_index[_indexOfCurrentObject] == currentlyRequestedIndex))
|
||||
{
|
||||
_indexOfCurrentObject++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this.Wait && _indexOfCurrentObject >= _index.Length)
|
||||
{
|
||||
this.EndProcessing();
|
||||
throw new StopUpstreamCommandsException(this);
|
||||
}
|
||||
|
||||
_indexCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The index of the active index filter.
|
||||
/// </summary>
|
||||
private int _currentFilterIndex;
|
||||
|
||||
/// <summary>
|
||||
/// The index of the object being processed.
|
||||
/// </summary>
|
||||
private int _currentObjectIndex;
|
||||
|
||||
/// <summary>
|
||||
/// Handles processing of InputObject if -Index or -SkipIndex is specified.
|
||||
/// </summary>
|
||||
private void ProcessIndexed()
|
||||
{
|
||||
if (_isIncludeIndex)
|
||||
{
|
||||
if (_currentFilterIndex < _index.Length)
|
||||
{
|
||||
int nextIndexToOutput = _index[_currentFilterIndex];
|
||||
if (_currentObjectIndex == nextIndexToOutput)
|
||||
{
|
||||
ProcessObjectAndHandleErrors(InputObject);
|
||||
while ((_currentFilterIndex < _index.Length) && (_index[_currentFilterIndex] == nextIndexToOutput))
|
||||
{
|
||||
_currentFilterIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!Wait && _currentFilterIndex >= _index.Length)
|
||||
{
|
||||
EndProcessing();
|
||||
throw new StopUpstreamCommandsException(this);
|
||||
}
|
||||
|
||||
_currentObjectIndex++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_currentFilterIndex < _index.Length)
|
||||
{
|
||||
int nextIndexToSkip = _index[_currentFilterIndex];
|
||||
if (_currentObjectIndex != nextIndexToSkip)
|
||||
{
|
||||
ProcessObjectAndHandleErrors(InputObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((_currentFilterIndex < _index.Length) && (_index[_currentFilterIndex] == nextIndexToSkip))
|
||||
{
|
||||
_currentFilterIndex++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ProcessObjectAndHandleErrors(InputObject);
|
||||
}
|
||||
|
||||
_currentObjectIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Completes the processing of Input.
|
||||
/// </summary>
|
||||
protected override void EndProcessing()
|
||||
{
|
||||
|
||||
@@ -244,6 +244,18 @@ Describe "Select-Object DRT basic functionality" -Tags "CI" {
|
||||
$results[0] | Should -BeExactly "3"
|
||||
}
|
||||
|
||||
It "Select-Object with SkipIndex should work" {
|
||||
$results = "1", "2", "3" | Select-Object -SkipIndex 0, 2
|
||||
$results | Should -HaveCount 1
|
||||
$results[0] | Should -BeExactly "2"
|
||||
}
|
||||
|
||||
It "Select-Object with SkipIndex should work with index out of range" {
|
||||
$results = 0..10 | Select-Object -SkipIndex 5, 6, 7, 8, 11
|
||||
$results | Should -HaveCount 7
|
||||
$results -join ',' | Should -BeExactly "0,1,2,3,4,9,10"
|
||||
}
|
||||
|
||||
It "Select-Object should handle dynamic (DLR) properties"{
|
||||
$dynObj = [TestDynamic]::new()
|
||||
$results = $dynObj, $dynObj | Select-Object -ExpandProperty FooProp
|
||||
|
||||
Reference in New Issue
Block a user