score:1

Accepted answer

This query does exactly the same as your function, if I'm not mistaken:

var repeated = str.GroupBy(s => s).Where(group => group.Any())
    .Select(group =>
    {
        var indices = Enumerable.Range(1, str.Count).Where(i => str[i-1] == group.Key).ToList();
        return string.Join(" - ", group.Select((s, i) => indices[i]));
    });

It firstly groups the items of the original list, so that every item with the same content is in a group. Then it searches for all indices of the items in the group in the original list, so that we have all the indices of the original items of the group. Then it joins the indices to a string, so that the resulting format is similiar to the one you requested. You could also transform this statement lambda to an anonymous lambda:

var repeated = str.GroupBy(s => s).Where(group => group.Any())
    .Select(group => string.Join(" - ",
        group.Select((s, i) =>
            Enumerable.Range(1, str.Count).Where(i2 => str[i2 - 1] == group.Key).ToList()[i])));

However, this significantly reduces performance.


I tested this with the following code:

public static void Main()
{
    var str = new List<string>
    {
        "bla",
        "bla",
        "baum",
        "baum",
        "nudel",
        "baum",
    };
    var copy = new List<string>(str);
    var repeated = str.GroupBy(s => s).Where(group => group.Any())
        .Select(group => string.Join(" - ",
            group.Select((s, i) =>
                Enumerable.Range(1, str.Count).Where(i2 => str[i2 - 1] == group.Key).ToList()[i])));
    var repeated2 = Repeat(str);
    var repeated3 = str.GroupBy(s => s).Where(group => group.Any())
        .Select(group =>
        {
            var indices = Enumerable.Range(1, str.Count).Where(i => str[i-1] == group.Key).ToList();
            return string.Join(" - ", group.Select((s, i) => indices[i]));
        });

    Console.WriteLine(string.Join("\n", repeated) + "\n");
    Console.WriteLine(string.Join("\n", repeated2) + "\n");
    Console.WriteLine(string.Join("\n", repeated3));
    Console.ReadLine();
}

public static List<string> Repeat(List<string> str)
{
    var distinctItems = str.Distinct();
    var repeat = new List<string>();
    foreach (var item in distinctItems)
    {
        var added = false;
        var reItem = "";
        for (var index = 0; index < str.LongCount(); index++)
        {
            if (item != str[index]) 
                continue;
            added = true;
            reItem += " - " + (index + 1);
        }

        if (added)
            repeat.Add(reItem.Substring(3));
    }

    return repeat;
}

Which has the followin output:

1 - 2
3 - 4 - 6
5

1 - 2
3 - 4 - 6
5

1 - 2
3 - 4 - 6
5

score:1

Inside your repeat method you can use following way to get repeated items

var repeated = str.GroupBy(s=>s)
      .Where(grp=>grp.Count()>1)
      .Select(y=>y.Key)
      .ToList();

Related Articles