Given
IList<int> indexes;
ICollection<T> collection;
What is the most elegant way to extract all T in collection based on the the indexes provided in indexes?
For example, if collection contained
"Brian", "Cleveland", "Joe", "Glenn", "Mort"
And indexes contained
1, 3
The return would be
"Cleveland," "Glenn"
Edit: Assume that indexes is always sorted ascending.
To get the index of item in a JavaScript set, we can convert the set into an array and then use the array indexOf method. to create a set with the Set constructor. Then we spread the set s into an array with the spread operator. Next, we call indexOf on the array with the value we want to find the index for.
An index can be defined on a Collection property (java. util. Collection implementation) or Array. Setting such an index means that each of the Collection's or Array's items is indexed.
Unlike List and arrays, Set does NOT support indexes or positions of it's elements. Set supports Generics and we should use it whenever possible. Using Generics with Set will avoid ClassCastException at runtime. We can use Set interface implementations to maintain unique elements.
This assumes that the index sequence is a monotone ascending sequence of non-negative indices. The strategy is straightforward: for each index, bump up an enumerator on the collection to that point and yield the element.
public static IEnumerable<T> GetIndexedItems<T>(this IEnumerable<T> collection, IEnumerable<int> indices)
{
int currentIndex = -1;
using (var collectionEnum = collection.GetEnumerator())
{
foreach(int index in indices)
{
while (collectionEnum.MoveNext())
{
currentIndex += 1;
if (currentIndex == index)
{
yield return collectionEnum.Current;
break;
}
}
}
}
}
Advantages of this solution over other solutions posted:
Disadvantages:
Here's a faster version:
IEnumerable<T> ByIndices<T>(ICollection<T> data, IList<int> indices)
{
int current = 0;
foreach(var datum in data.Select((x, i) => new { Value = x, Index = i }))
{
if(datum.Index == indices[current])
{
yield return datum.Value;
if(++current == indices.Count)
yield break;
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With