0

My question is simple, and I am quite sure the answer must be already here on SO, but could not find it.

And guys, an array is not a list and not an IEnumerable!!! Or are you telling me I HAVE to convert it to a list?

I want to get the index of a subarray (the first one) using Linq.

int[] arr= new int[] { 1, 5, 3, 2, 4 };
int[] sub= new int[] { 3, 2 };

int index = ? // Expected result 2

I looked at Array.FindIndex and Array.IndexOf, but couldn't figure it out.

Convering it to lists does not seem a very good plan. This has a dramatic performance:

List arrList = ((int[])arr).ToList(); List subList = ((int[])sub).ToList();

Thanks

RWC
  • 4,697
  • 2
  • 22
  • 29
  • Guys, that is not what I asked for, unless you tell me I have to convert my simple arrays to lists first. Please read the question! – RWC Dec 12 '18 at 10:24
  • @RWC: Please at least try the answers before telling that it's not what you have asked for. – Tim Schmelter Dec 12 '18 at 10:34
  • *"an array is not a list and not an IEnumerable"* - semantically you are correct, but since [array implements](https://learn.microsoft.com/en-us/dotnet/api/system.array?view=netframework-4.7.2) `IList`, which implements `IEnumerable` - you are wrong. – Sinatr Dec 12 '18 at 10:34
  • Okay, my question differs from the other question, because my question is implicitly about arrays. The fact that Array implements IList, does not make my question the same. Just say " Array implements IList, so you can use the answer given to another question". It does not make the question the same. Q: "Does a whale have lungs". A: "A cow is a mammal and has got longs, a whale is also a mammal, so a whale has got lungs." Really? – RWC Dec 12 '18 at 10:44

1 Answers1

2

You could use this method:

public static int GetIndex<T>(IList<T> largeList, IList<T> sublist)
{
    for (int i = 0; i < largeList.Count - sublist.Count; i++)
    {
        bool isContained = largeList.Skip(i).Take(sublist.Count).SequenceEqual(sublist);
        if (isContained)
            return i;
    }

    return -1;
}

or this more optimized but less readable implementation:

public static int GetIndex<T>(IList<T> largeList, IList<T> sublist, IEqualityComparer<T> comparer = null)
{
    if(comparer == null) comparer = EqualityComparer<T>.Default;
    for (int i = 0; i < largeList.Count - sublist.Count; i++)
    {
        bool allEqual = false; 
        for (int ii = 0; ii < sublist.Count; ii++)
        {
            allEqual = comparer.Equals(largeList[i + ii], sublist[ii]);
            if (!allEqual)
                break;
        }
        if (allEqual)
            return i;
    }

    return -1;
}
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939