NachoMiguel
NachoMiguel

Reputation: 993

getCount of Duplicates in List

I have this code:

public List<int> Duplicates(List<int> sequence)
{

    int[] countArr = new int[156];
    foreach (int i in sequence)
    {
        countArr[i]++;
    }

    List<int> resultList = new List<int>();

    for (var i = 0; i < countArr.Length; i++)
    {
        if (countArr[i] > 1)
        {
            resultList.Add(i);
        }
    }

    return resultList;
}

This is getting me the elements that are duplicated, but not how many times this elements are duplicated.

Thanks in advance for any help provided.

EDIT

I do not want to use LINQ

Upvotes: 0

Views: 63

Answers (4)

Tim Schmelter
Tim Schmelter

Reputation: 460028

That's a very complicated way you use, i'd rather return a Dictionary<int, int>:

public static Dictionary<int, int> Duplicates(IEnumerable<int> sequence)
{
    var duplicates = new Dictionary<int, int>();
    foreach (int i in sequence)
    {
        if(duplicates.ContainsKey(i))
            duplicates[i]++;
        else
            duplicates.Add(i, 1);
    }
    return duplicates;
}

Upvotes: 2

Callum Linington
Callum Linington

Reputation: 14417

Simple answer with dictionary:

void Main()
{
    List<int> intlist = new List<int>
    {
        1,
        1,
        1,
        2,
        2,
        3,
        4,
        4,
        4,
        4
    };


    var dict = new Dictionary<int, int>();
    foreach (var item in intlist)
    {
        if (!dict.ContainsKey(item)) // this checks for the existance of an item
        {
            dict.Add(item, 0); // this initialises the item in the dictionary
        }
        dict[item]++; // this will update the count of the item
    }

    // this is just for linqpad debug output and shows each value and their count
    // this can be achieved with foreach
    dict.Select(x => new { x.Key, x.Value}).Dump();
}

Debug output

Yes I know there is a Select at the bottom, but that has nothing to do with the duplicate collection.

Upvotes: 0

Maksim Simkin
Maksim Simkin

Reputation: 9679

Use GroupBy:

sequence.GroupBy(i => i).Select(g => new {Value = g.Key, Amount = g.Count()})

If you don't want to use Linq (why???) just collect value and amount together in a Tuple:

List<Tuple<int,int>> resultList = new List<Tuple<int,int>>();

for (var i = 0; i < countArr.Length; i++)
{
    if (countArr[i] > 1)
    {
        resultList.Add(Tuple.Create(i, countArr[i]));
    }
}

Upvotes: 2

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

Your algorithm already produces the required counts, so all you need to do is to arrange returning them to the caller in some way. One approach is to change the return type to IList<KeyValuePair<int,int>>. The collection of pairs you return would contain the number in the Key property, and its count in the Value property:

IList<KeyValuePair<int,int>> Duplicates(List<int> sequence) {
    var countArr = new int[156];
    foreach (int i in sequence) {
        countArr[i]++;
    }
    var resultList = new List<KeyValuePair<int,int>>();
    for (var i = 0; i < countArr.Length; i++) {
        if (countArr[i] > 1) {
            resultList.Add(new KeyValuePair<int,int>(i, countArr[i]));
        }
    }
    return resultList;
}

Upvotes: 1

Related Questions