score:3

Accepted answer

you could try this, although i have not performance tested it yet:

list<string> originallist = new list<string>()
{
    @"aaa\bbb",
    @"aaa\ccc",
    @"aaa\ccc",
    @"bbb\xxx",
    @"bbb",
    @"bbb\xxx",
    @"bbb\xxx"
};
list<string> outputlist = new list<string>();

foreach(var g in originallist.groupby(x => x).select(x => x.tolist()))
{   
    var index = 1;  
    foreach(var item in g)
    {
        outputlist.add(string.format("{0}[{1}]", item, index++));
    }
}

fiddle here

score:0

you could just use group() to pull the strings together and then project those groups using a combination of value and count.

given your list of strings:

var listofstrings;
var grouped = listofstrings.groupby(x => x);
var groupedcount = grouped.select(x => new {key = x.key, count = group.count()});

score:0

you can use this crisp and crunchy code:

public static void main()
{
    var originallist  = new list<string>()
    {
        @"aaa\bbb",
        @"aaa\ccc",
        @"aaa\ccc",
        @"bbb\xxx",
        @"bbb",
        @"bbb\xxx",
        @"bbb\xxx"
    };

    var outputlist = originallist.groupby(x => x).selectmany(x => x.select((y, i) => string.format("{0}[{1}]", y, i + 1)));     

    console.writeline(string.join("\n", outputlist));
}

score:0

using a hashset

note: dump() is a linqpad method that prints the results to the screen — substitute as necessary.

void main()
{
    var list = new list<string> {"hello", "doctor", "name", "continue", "yesterday", "tomorrow", "hello"};
    
    //case-insensitive string compare
    list.hasduplicates(stringcomparer.ordinalignorecase).dump();

    //case-sensitive string compare
    list.hasduplicates().dump();

    //integer compare
    var list2 = new list<int> { 1,2,3,4,5,2 };
    list2.hasduplicates().dump();
}

public static class test
{
    public static bool hasduplicates<t>(this ilist<t> list, stringcomparer stringcomparer = null)
    {
        if (typeof(t) == typeof(string))
        {
            var hash = new hashset<string>(list.count, stringcomparer);
            foreach (var val in list) if (!hash.add(val?.tostring())) break;
            return hash.count != list.count;
        }
        else
        {
            var hash = new hashset<t>(list.count);
            foreach (var val in list) if (!hash.add(val)) break;
            return hash.count != list.count;
        }
    }
}

/*

output:

true
false
true
*/

score:1

what about this?

    static ienumerable<string> mycounter(ienumerable<string> data)
    {
        var mydic = new dictionary<string, int>();
        foreach (var d in data)
        {
            if (!mydic.containskey(d))
                mydic[d] = 1;
            else
                mydic[d] = mydic[d] + 1 ;
            yield return d +"[" + mydic[d] + "]";
        }
    }

score:1

you could iterate over the list and use a dictionary to get the count, like this:

private int getcount(idictionary<string, int> counts, string item)
{
  int count;
  if (!counts.trygetvalue(item, out count))
    count = 0;
  count++;
  counts[item] = count;
  return count;
}

private ienumerable<string> getitems(ienumerable<string> items)
{
  // initialize dict for counts with appropriate comparison
  var counts = new dictionary<string, int>(stringcomparer.ordinalignorecase);
  foreach(var item in items)
    yield return string.format("{0}[{1}]", item, getcount(counts, item));
}

score:10

since you ask for fastest, the best imo would be to use foreach loop and counting dictionary<string, int>. it has the same time complexity as hashset and uses much less memory than linq groupby:

var counts = new dictionary<string, int>(pathlist.count); // specify max capacity to avoid rehashing
foreach (string item in pathlist)
{
    // do some stuff here and pick 'item' only if it fits some criteria.
    if (isvalid(item))
    {
        int count;
        counts.trygetvalue(item, out count);
        counts[item] = ++count;
        duplicateitems.add(item + "[" + count + "]");
    }
}

Related Query

More Query from same tag