novice in DotNet
novice in DotNet

Reputation: 791

C# Linq nearest index of a target element

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

Answers (3)

Evk
Evk

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

Matthew Watson
Matthew Watson

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

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

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

Related Questions