Search code examples
c#arraysienumerable

Get index array of value changes or first distinct values from array of Objects


I have a sorted array of objects that contains 3 doubles, lets call them x, y and z. I need to create an array of indexes for each transition point, example:

index   x   y   z
------------------
  0  |  3 | 2 | 1
  1  |  4 | 3 | 1
  2  |  3 | 1 | 1
  3  |  1 | 3 | 2
  4  |  3 | 1 | 2
  5  |  1 | 3 | 3
  6  |  1 | 3 | 3

Should give me the array {3,5} as that is the point where z changes, I have tried var ans = myObjectArr.Select(a => a.z).Distinct().ToList();but that simply gives me a list of the values themselves and not the index they are in the object array. The array is very large and i would like to avoid iterating my way through it discreetly. I feel like i'm just missing something silly and any help would be appreciated. Generating a list or an array would both be acceptable.

EDIT: I was under the impression that using Linq was faster than doing it iteratively, after reading comments i find this not to be the case and because of this Charlieface's answer is the best one for my problem.


Solution

  • var lastZ = myObjectArr[0].z;
    var zIndexes = new List<int>();
    for(var i = 1; i < myObjectArr.Length; i++)
    {
        if(myObjectArr[i] != lastZ)
        {
            lastZ = myObjectArr[i];
            zIndexes.Add(i);
        }
    }
    // or you can use obscure Linq code if it makes you feel better
    var zIndexes = myObjectArr
        .Select((o, i) => (o, i))
        .Skip(1)
        .Aggregate(
            new List<int>(),
            (list, tuple) => {
                if(tuple.o.z != lastZ)
                {
                    lastZ = tuple.o.z;
                    list.Add(tuple.i);
                }
                return list;
            } );