Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A library like Python's collections.Counter library for C# -> Getting the difference of values between two dictionary objects in C#

Tags:

python

c#

This is how I would create a Dictionary in C#.

   Dictionary<string, int> d = new Dictionary<string, int>()
    {
        {"cheese", 2},
        {"cakes", 1},
        {"milk", 0},
        {"humans", -1}  // This one's for laughs
    };

In Python if you have a dictionary like so:

from collections import Counter

my_first_dict = {
    "cheese": 1,
    "cakes": 2,
    "milk": 3,
}

my_second_dict = {
    "cheese": 0,
    "cakes": 1,
    "milk": 4,
}

print Counter(my_first_dict) - Counter(my_second_dict)

>>> Counter({'cheese': 1, 'cakes': 1})

As you can see, Counter is very useful when comparing dictionary objects.

Is there a library in C#, that will allow me to do something similar to this, or do I have to code it from scratch?

like image 846
Games Brainiac Avatar asked Sep 26 '13 16:09

Games Brainiac


People also ask

What is Python collections counter?

Python Counter Counter is an unordered collection where elements are stored as Dict keys and their count as dict value. Counter elements count can be positive, zero or negative integers. However there is no restriction on it's keys and values.

What is counter library in Python?

A Counter is a dict subclass for counting hashable objects. It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. Counts are allowed to be any integer value including zero or negative counts.

Is counter in Python standard library?

Counter() class is pretty handy. It only takes a few lines of code to implement something like that; but it's nice that it's in the standard libraries when you remember to use it.


1 Answers

You can join the two dictionaries together and then create a new one based on the given operation with only a few lines of code:

Dictionary<string, int> d1 = new Dictionary<string, int>();
Dictionary<string, int> d2 = new Dictionary<string, int>();

var difference = d1.Join(d2, pair => pair.Key, pair => pair.Key, (a, b) => new
{
    Key = a.Key,
    Value = a.Value - b.Value,
})
.Where(pair => pair.Value > 0)
.ToDictionary(pair => pair.Key, pair => pair.Value);

There is no system class that you've shown that wraps a dictionary an provides a - operator for them, but you can make your own if you want easily enough:

public class Counter<T> : IEnumerable<KeyValuePair<T, int>>
{
    private IEnumerable<KeyValuePair<T, int>> sequence;
    public Counter(IEnumerable<KeyValuePair<T, int>> sequence)
    {
        this.sequence = sequence;
    }

    public static Counter<T> operator -(Counter<T> first, Counter<T> second)
    {
        return new Counter<T>(first.Join(second
            , pair => pair.Key, pair => pair.Key, (a, b) =>
                new KeyValuePair<T, int>(a.Key, a.Value - b.Value))
            .Where(pair => pair.Value > 0));
    }

    public IEnumerator<KeyValuePair<T, int>> GetEnumerator()
    {
        return sequence.GetEnumerator();
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}
like image 190
Servy Avatar answered Sep 25 '22 23:09

Servy