Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using a Boolean Array as Custom Dictionary Key

Tags:

c#

.net

I am trying to make a Dictionary in C# that uses a boolean array for its keys.

 Dictionary<bool[], string> 

The bool array has fixed length of 1000, and all are the same length. I'm having trouble with the hashcode and the common method of an 'exclusive or' doesn't make as much sense because of the length of the array.

Similar questions on StackOverflow are addressed with the 'exclusive or' in the GetHashCode method. I don't think that works in this context. I would like to use it as:

 Dictionary<bool[], string> myDict = 
             new Dictionary<bool[], string>(EqualityComparer);

where EquaityComparer does something like:

   public class EqualityComparer : IEqualityComparer<bool[]>
    {
        public bool Equals(bool[] x, bool[] y)
        {
            return x.SequenceEqual(y);
        }

        public int GetHashCode(bool[] x)
        {
            // this part doesn't work correctly
            int hc = x.GetHashCode();
            return hc;
        }
    }

Of course all of the usual concerns about the bool array being mutable and the size of any derived key being relevant to performance apply here...though I don't have a solution.

like image 937
Vic Avatar asked Jul 17 '12 17:07

Vic


People also ask

Can a dictionary key be an array?

A dictionary's item is a value that is unambiguously associated with a unique key and the key is used to retrieve the item. The key can be of any type except a variant or an array (but generally it is a string or still an integer).

How do you declare a boolean array in Javascript?

Syntax. // initialization of boolean array with Array. from() method let arrName = Array. from({length}, (value,index)=> true/false);

Can tuple be used as dictionary key in C#?

Answer. Yes, a tuple is a hashable value and can be used as a dictionary key. A tuple would be useful as a key when storing values associated with a grid or some other coordinate type system.

How do you push a boolean to an array?

To initialize an array of boolean values, use the Array() constructor to create an array of a specific length and call the fill() method on the array to populate it with booleans, e.g. new Array(3). fill(false) creates an array with 3 elements with a value of false . Copied!


2 Answers

For performance and consistency I would recommend storing your bool[] in another class. You know already that the key may not change so you can take advantage of this by storing the hash in the key class. The dictionary internal operations may use this hash multiple times for a single access (we are not supposed to have to know the internal implementation details though so it's best to assume this may be executed many times).

For performance you may still want to access or even keep a reference to the bool[] externally but the safest technique would be to make a safe copy in the key class.

public class BoolArrayKey
{
    private int hash;
    private bool[] data;

    public BoolArrayKey(bool[] source)
    {
        data = new bool[source.Length];
        Array.Copy(source, data, source.Length);
    }

    public override bool Equals(object obj)
    {
        BoolArrayKey other = obj as BoolArrayKey;
        if (other == null)
        {
            return false;
        }

        return other.data.SequenceEqual(data);
    }

    public override int HashCode()
    {
        if (hash == 0)
        {
            // Mark's hash implementation here, store the result in `hash`.
        }

        return hash;    
    }
}

If a you expect a frequent hash value of 0 then you could use another bool variable to indicate if the value had been computed.

like image 23
Kevin Brock Avatar answered Oct 05 '22 10:10

Kevin Brock


Both your Equals and HashCode are incorrect.

Presumably you wish to use SequenceEqual to compare the arrays for equality, or else a simple for loop.

To calculate a hashcode you can use any of the standard methods. It is very important that if two items compare equal then they must have the same hash.

Example

public int GetHashCode(bool[] x)
{
    int result = 29;
    foreach (bool b in x)
    {
        if (b) { result++; }
        result *= 23;
    }
    return result;
}

Related

  • Guidelines and rules for GetHashCode
like image 151
Mark Byers Avatar answered Oct 05 '22 11:10

Mark Byers