2

Given the following strings = new string[] { "a", "a", "a", "b", "b", "c", "c", "c", "c", "d" };

How would you replace the duplicate items to produce the following output: { "a", "Duplicate", "Duplicate", "b", "Duplicate", "c", "Duplicate", "Duplicate", "Duplicate", "d" }

0

5 Answers 5

7

For something like this, particularly if you intend to modify the array and not produce a new sequence, I would prefer an old fashioned loop. It would seem to me to be more obvious, less "clever," and easier to understand. If you are of a similar opinion, the loop is fairly easy to write. Create a set that will hold distinct items, and replace items that have already been added to the set.

var set = new HashSet<string>();
for (int i = 0; i < strings.Length; i++)
{
    if (set.Contains(strings[i]))
    {
        strings[i] = "Duplicate";
    }
    else
    {
        set.Add(strings[i]);
    }
}

Given your input, your output would be:

a
Duplicate
Duplicate
b
Duplicate
c
Duplicate
Duplicate
Duplicate
d
Sign up to request clarification or add additional context in comments.

4 Comments

Just wanted to write this down. IMHO this should be the right answer.
Good anti LINQ overuse answer! But to make it even better comparable to the "elegant" LINQ way in the other answer, the loop body can be reduced to if (!set.Add(strings[i])) strings[i] = "Duplicate";
Bit off-topic: What are the pros and cons of using HashSet instead of eg. Array or List in this example?
4

Using Linq, you could do this.

s = s.GroupBy(x=>x)
     .SelectMany(x=>x.Take(1)                                    // Take first element
                     .Concat(x.Skip(1).Select(r=>"Duplicate"))   // Replace other elements with 'Duplicate' 
                )
    .ToArray(); 

Check Working example

4 Comments

Very elegant way of doing it.
@nik0lias, may be elegant(I personally don't find this code elegant. Take this code and show somebody and ask him what does it do without debugging), but I suspect this will be inefficient comparing to straightforward methods.
@nik0lias Elegant? I make it a habit of asking c# candidates in their interviews about what these fancy Linq statements actually do. Let's just say that from the many hundreds of candidates that I've talked with, I have yet to interview the first person that actually knows what statements like this one do under the hood. IMHO that's pretty much the definition of a 'bad practice'.
I'd question those who didn't have an idea of what the above statement is doing. I wouldn't implement that unless I had an idea of the queries behind it. I don't just blindly type LINQ queries nor do I expect others to. If you understand it then it's elegant (IMO).
2

In case you are searching for a method which will mark only consecutive duplicates:

var strings = new string[] { "a", "a", "a", "b", "b", "c", "c", "c", "c", "d" };
var output = new string[strings.Length];
output[0] = strings[0];

for(int i = 1; i < strings.Length; i++)
{
    output[i] = strings[i] != strings[i - 1] ? strings[i] : "duplicate";
}

3 Comments

What if the input array is not a sorted array?.
Just want to let you know that OP not mentioned it is ordered list.
@HariPrasad, it has not have to be sorted in case he wants only consecutive duplicates.
0

Try This

strings = new string[] { "a", "a", "a", "b", "b", "c", "c", "c", "c", "d" };
var myArray = new System.Collections.ArrayList();

foreach(var item in strings){
    if (!myArray.Contains(item))
        myArray.Add(item);
    else
        myArray.Add('Duplicate');
}

1 Comment

A couple of things: ArrayList is not a preferred collection to use in modern C#, there are better choices. Secondly, this solution will become increasingly slow as the size of strings grows, it will not scale well.
0

Just a thought on writing a lambda expression for this

var output = strings.ToList().Select((x, y) => Array.IndexOf(strings, x) == y ? x : "Duplicate");

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.