Add '-SkipIndex' parameter to 'Select-Object' (#7483)

This commit is contained in:
Staffan Gustafsson
2018-08-09 11:59:54 -07:00
committed by Dongbo Wang
parent 791159d615
commit 618d9f31a0
2 changed files with 110 additions and 27 deletions
@@ -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