Reputation: 791
Is it possible to create linq to find nearest index of a target element in C# 4.0? Example, I have an array
string[] array=new string[]
{"","","source","","source2","","","destination","source3","destination"};
the "destination" is found at 7 and 9, the nearest index of "destination" to 2 ("source") should be 7,not 9.
The current solution I know using if condition is,
int index(int sourceIndex,string[] array,string destination)
{
int temp=sourceIndex;
while(temp<array.Length)
{
if(array[sourceIndex]==destination)
return sourceIndex;
temp++;
}
return -1;
}
Edited To Add: I need to find the destination In the increasing order in the forward direction My main question being, find nearest index of a target element in an array in forward direction. Thanks in advance
Upvotes: 0
Views: 213
Reputation: 101543
If you really want to use linq for this (say you have IEnumerable
and not really an array), you can do it like this:
static int index(int sourceIndex, IEnumerable<string> array, string destination)
{
return array
// convert items stream into (item, index) pair
.Select((item, index) => new { Item = item, Index = index })
// skip items until condition is met
.SkipWhile(c => c.Index <= sourceIndex || c.Item != destination)
// we need index only
.Select(c => c.Index)
// if we found nothing - return -1
.DefaultIfEmpty(-1)
.First();
}
If you have an array - please don't do this and use Matthew Watson answer.
Upvotes: 1
Reputation: 109742
If you actually have an array, I don't think you need to use Linq for this.
It would be much simpler to do this:
int startIndex = 2;
int nearest = Array.IndexOf(array, "destination", startIndex+1);
Then nearest
will contain the result you're looking for, or -1 if "destination"
can't be found.
Note: this only finds the nearest in the forward direction, which I assume is what you want given your statement: "Source index is known and nearest in the forward direction , if there is no occurence, it need not return"
Also note that I used startIndex+1
because we don't need to start searching at the first position.
Upvotes: 4
Reputation: 250056
Not necessarily the most efficient solution, but if you don't expect a lot of matches it should work:
string[] array = new string[] {"","","source","","source2","","","destination","source3","destination"};
var withIndex = array.Select((Value, Index) => new { Index, Value });
var result =
(from dest in withIndex.Where(_ => _.Value == "destination")
from source in withIndex.Where(_ => _.Value == "source")
let dif = dest.Index - source.Index
orderby dif
select dest.Index)
.FirstOrDefault();
We first the occurrences of source
and destination
and we the find the smallest difference.
Upvotes: 1