I have this function, which works and gives the correct result:
Pu
You could do it using GroupBy
and if you want to preserve the original order you can create an anonymous type to include it, then group, then re-sort by the original order.
string[] input = new[]{ "Apple", "Orange", "Apple", "Pear", "Banana",
"Apple", "Apple", "Orange" };
var result = input
// Remember the initial order
.Select((name, i) => new {name, i})
.GroupBy(x => x.name)
// Now label the entries in each group
.SelectMany(g => g.Select((item, j) =>
new {i = item.i, name = (j == 0 ? item.name : item.name + (j+1))}))
// Now reorder them by their original order
.OrderBy(x => x.i)
// Remove the order value to get back to just the name
.Select(x => x.name)
.ToList();
foreach (var r in result)
Console.WriteLine(r);
Result
Apple
Orange
Apple2
Pear
Banana
Apple3
Apple4
Orange2