So for example, I have an array like that:

char[] pattern = "GCAGAGAG".ToCharArray();

And what I would like to do is to extract out distinct values and its corresponding indexes(smallest one) from right to left where first letters does not count.
example:

reversed array: GAGAGACG
Distinct values are: A, C, G
and the smallest index of each one is:
G = 2 (first G does not count)
A = 1
C = 6

So far I managed to do this but then I freeze, because I lack of knowledge connected with linq. I am still learning those things, so I am kind of "green" at them :)

var query = Pattern
                        .Reverse()
                        .Select((n, i) => new { Letter = n, Index = i })
                        .Where(n => n.Index > 0)
                        .OrderBy(n => n.Letter);

This gives the result, which is in attached picture.
Now I should group values by letter and find their min index value, but here I'll need your's help.

At the end I would like to cast result to dictionary but I am having trouble with it ... I tried with

.ToDictionary<char, int>(n => n.Letter, n => n.Index);

but that gives me an error. So how should I form this?

Attachments sample.jpg 19.06 KB

You can solve it by creating a concrete type. Here's one such type, simply named LetterHolder.

class LetterHolder
{
    public char Letter { get; set; }
    public int Index { get; set; }
}

And then getting a dictionary.

char[] Pattern = "GCAGAGAG".ToCharArray();

Dictionary<char,int> dictionary = 
            Pattern
            .Reverse()
            .Select((n, i) => new { Letter = n, Index = i })
            .Where(n => n.Index > 0)
            .GroupBy(n => n.Letter)
            .Select(n => new LetterHolder { Letter = n.Key, Index = n.Min(g => g.Index) })
            .ToDictionary<LetterHolder, char, int>(l => l.Letter, l => l.Index);


foreach (var pair in dictionary)
    Console.WriteLine(pair.Key + " " + pair.Value.ToString());

To be honest, though, something like this is going to be better performant, as it will only need to go over the array once.

Dictionary<char, int> dict2 = new Dictionary<char, int>();
int maxIndex = Pattern.Length - 1;
char temp;
for (int i = 1; i < maxIndex; i++)
{
    temp = Pattern[maxIndex - i];
    if (!dict2.ContainsKey(temp))
        dict2.Add(temp, i); // reverse position index
}

Edited 6 Years Ago by apegram: n/a

Thanks you apegram. I insert your solution into my code & it works like a charm :)

This question has already been answered. Start a new discussion instead.