Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dictionary with Func as key

I am wondering if this is a sane choice of key for a dictionary? What I want to do is use an expression as the key in a dictionary, something like:

    var map3 = new Dictionary<Func<int, bool>, int>();
    map3.Add((x) => x % 2 == 0, 1);
    map3.Add((x) => x % 10 == 0, 2);
    // ...

    var key = map3.Keys.SingleOrDefault(f => f(2));
    // key = (x) => x % 2
    // map3[key] = 1

The idea being this is a cleaner way than having big if-else or switch statements.

Does this make sense? Will it work? Is there an simpler way?

like image 459
user380689 Avatar asked Nov 16 '12 02:11

user380689


People also ask

Can a function be a key in a dictionary python?

Dictionaries in Python Almost any type of value can be used as a dictionary key in Python. You can even use built-in objects like types and functions. However, there are a couple restrictions that dictionary keys must abide by. First, a given key can appear in a dictionary only once.

Can a dictionary hold a function?

Functions are first class objects in Python and so you can dispatch using a dictionary.

Can a dictionary contain an array as a key?

A dictionary is sometimes called an associative array because it associates a key with an item. The keys behave in a way similar to indices in an array, except that array indices are numeric and keys are arbitrary strings. Each key in a single Dictionary object must be unique.

Can a dictionary have a key without a value?

There is no such thing as a key without a value in a dict. You can just set the value to None, though.


2 Answers

Considering the way that you use your map, you will be better off with a List<Tuple<Func<int,bool>,int>>, because the order of checking the lambdas will no longer be arbitrary, as in a hash-based dictionary. This approach also lets you skip the lookup step:

var map3 = new List<Tuple<Func<int,bool>,int>> {
    new Tuple<Func<int,bool>,int>((x) => x % 2 == 0, 1)
,   new Tuple<Func<int,bool>,int>((x) => x % 10 == 0, 2)
};
var t = map3.SingleOrDefault(t => t.Item1(2));
if (t != null) {
    var v = t.Item2;
}
like image 156
Sergey Kalinichenko Avatar answered Sep 21 '22 13:09

Sergey Kalinichenko


Rewriting @dasblinkenlight's answer with latest syntax:

void Main()
{
    var map3 = new List<(Func<int, bool> Key, int Value)> {
        (Key: (x) => x * 2 == 4, Value: 1),
        (Key: (x) => x * 10 == 100, Value: 2)
    };

    var result = map3.SingleOrDefault(x => x.Key(10));
    Console.WriteLine(result.Value);
}

When Key evaluates to a Func which is not there on the List SingleOrDefault returns an element with key null and value 0.

Key and Value above are for readability, they can be removed and in that case result.Intem2 will produce output

like image 31
Amit Avatar answered Sep 17 '22 13:09

Amit