containsValues checking Dictionary<type, object> c# - c#

with ECPoint class :
public class ECPoint
{
private BigInteger p, x, y;
public BigInteger P
{
get { return p; }
set { p = value; }
}
public BigInteger X
{
get { return x; }
set { x = value; }
}
public BigInteger Y
{
get { return y; }
set { y = value; }
}
public ECPoint(BigInteger p, BigInteger x, BigInteger y)
{
this.p = p;
this.x = x;
this.y = y;
}
}
I have a dictionary in C#:
Dictionary<BigInteger, ECPoint> hashTable = new Dictionary<BigInteger, ECPoint>();
and an object of ECPoint Class :
ECPoint gamma = new ECPoint(p, Qx, Qy);
p,Qx,Qy are numerical values
And I did this test :
if (hashTable.ContainsValue(gamma))
{
BigInteger j = -1;
foreach (KeyValuePair<BigInteger, ECPoint> s in hashTable)
{
if (s.Value.X==gamma.X && s.Value.Y==gamma.Y)
{
j = s.Key;
return m*j;
}
}
}
The problem is this test has never given a true value, it is always false, so how to check if the dictionary hashTable contain the values of an object?. Someone can help me, thanks in advance, and I apologize for my English.

You can use FirstOrDefault() linq function to check and get value from hashTable so you don't have to iterate with foreach.
Your code will be like this:
var data = hashTable.FirstOrDefault(a => a.Value.X == gamma.X && a.Value.Y == gamma.Y);
if(data != null){
return data.Key * m;
}

You could either implement Equal and GetHashCode or turn ECPoint into a structure so the compare no longer uses a reference comparison.

Related

How to handle nulls in IEqualityComparer?

The following method is from XUnit Assert class:
public static void Equal<T>(IEnumerable<T> expected, IEnumerable<T> actual, IEqualityComparer<T> comparer);
And I am using it as:
IEnumerable<Decimal?> x = getXValues();
IEnumerable<Decimal?> y = getYValues();
Assert.Equal(x, y, new DecimalToleranceEqualityComparer(0.01m));
I am using an IEqualityComparer because is fine to consider 2.526 equal to 2.524.
I get an error because DecimalToleranceEqualityComparer is only for Decimal ...
x and y might have null values. DecimalToleranceEqualityComparer is:
public class DecimalToleranceEqualityComparer : IEqualityComparer<Decimal> {
private readonly Decimal _tolerance;
public DecimalToleranceEqualityComparer(Decimal tolerance) {
_tolerance = tolerance;
}
public Boolean Equals(Decimal x, Decimal y) {
return Math.Abs(x - y) <= _tolerance;
}
public Int32 GetHashCode(Decimal obj) {
return obj.GetHashCode();
}
}
I suppose if 2 values are nulls they should be consider equal ...
How to change the IEqualityComparer so that it handles nulls?
This code works for me. The real trick is in the imlementation of the Equals method. Also keep in mind the null check in the GetHashCode.
static void Main(string[] args)
{
IEnumerable<Decimal?> x = new List<Decimal?> { 1.51m, 3, null };
IEnumerable<Decimal?> y = new List<Decimal?> { 1.6m, 3, null };
Assert.Equal(x, y, new DecimalToleranceEqualityComparer(0.1m));
}
public class DecimalToleranceEqualityComparer : IEqualityComparer<Decimal?>
{
private readonly Decimal _tolerance;
public DecimalToleranceEqualityComparer(Decimal tolerance)
{
_tolerance = tolerance;
}
public Boolean Equals(Decimal? x, Decimal? y)
{
if (!x.HasValue && !y.HasValue)
{
// Both null -> they are equal
return true;
}
else if (!x.HasValue || !y.HasValue)
{
// One is null, other is not null -> not equal
return false;
}
else
{
// both have values -> run the actual comparison
return Math.Abs(x.Value - y.Value) <= _tolerance;
}
}
public Int32 GetHashCode(Decimal? obj)
{
if (obj.HasValue)
{
return obj.GetHashCode();
}
else
{
// Here decide what you need
return string.Empty.GetHashCode();
}
}
}
One option that comes to mind could be implementing new equality comparer for nullable decimal type IEqualityComparer<decimal?> which could use your existing DecimalToleranceEqualityComparer internally. Something like
public Boolean Equals(Decimal? x, Decimal? y) {
return (x.HasValue && y.HasValue)?
_decimalToleranceEqualityComparer.Equals(x.Value,y.Value)
: x == y;
}
You are supplying a list of Nullable<decimal>'s and your IEqualityComparer is expecting a list of Decimal's.
With a rewrite like this you should be fine:
public class DecimalToleranceEqualityComparer : IEqualityComparer<decimal?>
{
private readonly decimal _tolerance;
public DecimalToleranceEqualityComparer(decimal tolerance)
{
_tolerance = tolerance;
}
public bool Equals(decimal? x, decimal? y)
{
if (!x.HasValue && !y.HasValue) return true;
if (!x.HasValue || !y.HasValue) return false;
return Math.Abs(x.Value - y.Value) <= _tolerance;
}
public int GetHashCode(decimal? obj)
{
return obj.GetHashCode();
}
}

Breakpoint in Equals implimentation on IEqualityComparer<CustomClass> is never hit

I have a simple custom class Point:
public class Point: IEqualityComparer<Point>
{
public double X;
public double Y;
public double Z;
private double[] startPointCoords;
public Point()
{
}
public Point(double[] pointArray)
{
this.startPointCoords = pointArray;
X = pointArray[0];
Y = pointArray[1];
Z = pointArray[2];
}
public bool Equals(Point x, Point y)
{
if(x.X == y.X && x.Y == y.Y && x.Z == y.Z)
{
return true;
}
return false;
}
public int GetHashCode(Point obj)
{
string xString = X.ToString().Replace(".", "");
string yString = Y.ToString().Replace(".", "");
string zString = Z.ToString().Replace(".", "");
int xInt = Convert.ToInt32(xString);
int yInt = Convert.ToInt32(yString);
int zInt = Convert.ToInt32(zString);
return xInt - yInt + zInt;
}
}
I am using this class in a Dictionary. I am checking for if the point instance has been added to the dictionary using:
if (!pointsToProcess.ContainsKey(startPoint))
{
pointsToProcess.Add(startPoint, startPoint);
}
I am debugging my code to make sure Equals is working correctly. My break point I have set in Point.Equals is never hit. I set a break point in Point.GetHashCode and it is never hit either. It seems like they are not being used.
I know that there are classes called Point in .Net. I am absolutely sure that all the Point that I have in my code is from my custom namespace.
Why would my Point.Equals and Point.GetHashCode not be reached when setting a break point?
The Equals(a, b) method is not hit by IEquatable, so you'll need to tailor it to suit the interface.
Try this one:
public class Point : IEquatable<Point>
{
public double X;
public double Y;
public double Z;
private double[] startPointCoords;
public Point()
{
}
public Point(double[] pointArray)
{
this.startPointCoords = pointArray;
X = pointArray[0];
Y = pointArray[1];
Z = pointArray[2];
}
public override bool Equals(object obj) => Equals(obj as Point);
public bool Equals(Point other)
{
if (other is null)
return false;
if (ReferenceEquals(this, other))
return true;
return this.X == other.X &&
this.Y == other.Y &&
this.Z == other.Z;
}
public override int GetHashCode()
{
string xString = X.ToString().Replace(".", "");
string yString = Y.ToString().Replace(".", "");
string zString = Z.ToString().Replace(".", "");
int xInt = Convert.ToInt32(xString);
int yInt = Convert.ToInt32(yString);
int zInt = Convert.ToInt32(zString);
return xInt - yInt + zInt;
}
}
Also there are a lot of ways to implement hashcodes in C# for custom objects. While not perfect, one simple way would be using anonymous object hashing:
public override int GetHashCode()
{
return new { X, Y, Z }.GetHashCode();
}

Deserialization causes copies of List-Entries

I'd like to create a very general Model-Layer, which can also be passed arround as JSON. One Model should show a LED-Panel of a RaspberryPi2. Since I'd like to model the Class to be as near as possible to the reality, I force a List to always have 8 * 8 Leds. The Class is looking like this:
public class VisualLedPanel
{
private readonly Lazy<List<VisualLed>> _lazyVisualLeds = new Lazy<List<VisualLed>>(CreateVisualLeds);
public VisualLed this[int x, int y]
{
get
{
var result = VisualLeds.FirstOrDefault(f => f.X == x && f.Y == y);
return result;
}
}
public IEnumerable<VisualLed> VisualLeds
{
get
{
return _lazyVisualLeds.Value;
}
set
{
var tt = value;
}
}
private static List<VisualLed> CreateVisualLeds()
{
var result = new List<VisualLed>();
for (var x = 0; x <= 7; x++)
{
for (var y = 0; y <= 7; y++)
{
result.Add(new VisualLed(x, y));
}
}
return result;
}
}
The problem arises with the Serialization: I'm using the NewtonSoft. Json.Net Serializer, and as far as I've seen, it first accesses the Getter, which causes the Logic to create the Leds, and then sets them afterwards.
The only solution I could think of would either be a Custom-Deserializer or some sort of Constructor shennenigans.
It also seems like the Deserializer doesn't use the Set-Property of the VisualLeds-Value, since my Debugger-Stop never was hitted.
Is there an easy possibility arround to have the best of both worlds? I'd like to have the Model as general as possible without the need of Custom-Deserializer.
The easiest way for you to do this without having to write your own custom JsonConverter will be to serialize your collection of VisualLed objects as a proxy array property, marking the original property as ignored:
public class VisualLedPanel
{
private readonly Lazy<List<VisualLed>> _lazyVisualLeds = new Lazy<List<VisualLed>>(CreateVisualLeds);
public VisualLed this[int x, int y]
{
get
{
var result = VisualLeds.FirstOrDefault(f => f.X == x && f.Y == y);
return result;
}
}
[JsonIgnore]
public IEnumerable<VisualLed> VisualLeds
{
get
{
return _lazyVisualLeds.Value;
}
}
[JsonProperty("VisualLeds")]
VisualLed [] SerializableVisualLeds
{
get
{
return VisualLeds.ToArray();
}
set
{
if (value == null || value.Length == 0)
{
if (_lazyVisualLeds.IsValueCreated)
_lazyVisualLeds.Value.Clear();
}
else
{
_lazyVisualLeds.Value.Clear();
_lazyVisualLeds.Value.AddRange(value);
}
}
}
private static List<VisualLed> CreateVisualLeds()
{
var result = new List<VisualLed>();
for (var x = 0; x <= 7; x++)
{
for (var y = 0; y <= 7; y++)
{
result.Add(new VisualLed(x, y));
}
}
return result;
}
}
Prototype fiddle
For a further discussion, see Why are all the collections in my POCO are null when deserializing some valid json with the .NET Newtonsoft.Json component. Using ObjectCreationHandling.Replace would not be appropriate in this case since you want your Lazy<List<VisualLed>> _lazyVisualLeds to be read-only.

Compare two arbitrary JToken-s of the same structure

I would like to compare two arbitrary JTokens of the same type and structure (Json.Net from NewtonSoft).
static int CompareTokens(JToken x, JToken y);
// possible output: 0 / 1 / -1
The main goal is to be able use this method to sort two Json strings, so that even if in the beginning they had the same data, but in the different order, in the end these are two exactly same strings. So the sort criterion doesn't really matter, it just matters that this criterion is always the same. And each small element of data should be taken into account.
JToken can be of one of next several types: Array, Boolean, Date, Float, Guid, Integer, Null, Object, Property, String, TimeSpan, Uri. I don't take into account comparing Bytes, Comment, Constructor, None, Undefined, Raw.
It would be great to gain some idea about comparing JArrays and JObjects. That should be some recursive comparison, because JArrays may consist of other JArrays and JObjects and vice versa. Any idea would be appreciated.
But knowing about comparing simpler types would also be very helpful. I wonder rather about knowing how to convert from JToken to actual type (than about knowing how to do it logically).
JValue has IComparable implemented, but I didn't figure out how to convert simple typed JToken to JValue. Knowing about this would also be helpful.
In Linq-to-JSON, JValue represents a primitive value (string, number, boolean, and so on). It implements IComparable<JValue>, so Json.NET takes care of sorting primitive values for you.
Building off of that, you're going to need to recursively descend the two JToken object hierarchies in parallel. When you encounter the first token with a different .Net type, or different properties (if not a JValue), or with a different value (if a JValue), you need to return back the comparison value.
Keep in mind the following:
A comparison method should be reflexive, antisymmetric and transitive.
Container tokens of different .Net type need to be ordered by type in some consistent manner.
the child tokens of JArray and JConstructor are ordered.
the child tokens of JObject are not, so they need to be compared in some stable, symmetric manner. Walking both in order of property name would seem to work.
There is no obvious way to compare JRaw, so don't try, and let an exception get thrown.
The following is a prototype implementation:
public class JTokenComparer : IComparer<JToken>
{
public static JTokenComparer Instance { get { return instance; } }
static JTokenComparer instance;
static JTokenComparer()
{
instance = new JTokenComparer();
}
readonly Dictionary<Type, KeyValuePair<int, IComparer<JToken>>> dict;
JTokenComparer()
{
dict = new Dictionary<Type, KeyValuePair<int, IComparer<JToken>>>
{
// Order chosen semi-arbitrarily. Putting values first seems reasonable though.
{typeof(JValue), new KeyValuePair<int, IComparer<JToken>>(0, new JValueComparer()) },
{typeof(JProperty), new KeyValuePair<int, IComparer<JToken>>(1, new JPropertyComparer()) },
{typeof(JArray), new KeyValuePair<int, IComparer<JToken>>(2, new JArrayComparer()) },
{typeof(JObject), new KeyValuePair<int, IComparer<JToken>>(3, new JObjectComparer()) },
{typeof(JConstructor), new KeyValuePair<int, IComparer<JToken>>(4, new JConstructorComparer()) },
};
}
#region IComparer<JToken> Members
public int Compare(JToken x, JToken y)
{
if (x is JRaw || y is JRaw)
throw new InvalidOperationException("Tokens of type JRaw cannot be sorted");
if (object.ReferenceEquals(x, y))
return 0;
else if (x == null)
return -1;
else if (y == null)
return 1;
var typeData1 = dict[x.GetType()];
var typeData2 = dict[y.GetType()];
int comp;
if ((comp = typeData1.Key.CompareTo(typeData2.Key)) != 0)
return comp;
if (typeData1.Value != typeData2.Value)
throw new InvalidOperationException("inconsistent dictionary values"); // Internal error
return typeData2.Value.Compare(x, y);
}
#endregion
}
abstract class JTokenComparerBase<TJToken> : IComparer<JToken> where TJToken : JToken
{
protected TJToken CheckType(JToken item)
{
if (item != null && item.GetType() != typeof(TJToken))
throw new ArgumentException(string.Format("Actual type {0} of token \"{1}\" does not match expected type {2}", item.GetType(), item, typeof(TJToken)));
return (TJToken)item;
}
protected bool TryBaseCompare(TJToken x, TJToken y, out int comparison)
{
CheckType(x);
CheckType(y);
if (object.ReferenceEquals(x, y))
{
comparison = 0;
return true;
}
else if (x == null)
{
comparison = -1;
return true;
}
else if (y == null)
{
comparison = 1;
return true;
}
comparison = 0;
return false;
}
protected abstract int CompareDerived(TJToken x, TJToken y);
protected int TokenCompare(JToken x, JToken y)
{
var tx = CheckType(x);
var ty = CheckType(y);
int comp;
if (TryBaseCompare(tx, ty, out comp))
return comp;
return CompareDerived(tx, ty);
}
#region IComparer<JToken> Members
int IComparer<JToken>.Compare(JToken x, JToken y)
{
return TokenCompare(x, y);
}
#endregion
}
abstract class JContainerOrderedComparerBase<TJToken> : JTokenComparerBase<TJToken> where TJToken : JContainer
{
protected int CompareItemsInOrder(TJToken x, TJToken y)
{
int comp;
// Dictionary order: sort on items before number of items.
for (int i = 0, n = Math.Min(x.Count, y.Count); i < n; i++)
if ((comp = JTokenComparer.Instance.Compare(x[i], y[i])) != 0)
return comp;
if ((comp = x.Count.CompareTo(y.Count)) != 0)
return comp;
return 0;
}
}
class JPropertyComparer : JTokenComparerBase<JProperty>
{
protected override int CompareDerived(JProperty x, JProperty y)
{
int comp;
if ((comp = x.Name.CompareTo(y.Name)) != 0)
return comp;
return JTokenComparer.Instance.Compare(x.Value, y.Value);
}
}
class JObjectComparer : JTokenComparerBase<JObject>
{
protected override int CompareDerived(JObject x, JObject y)
{
int comp;
// Dictionary order: sort on items before number of items.
// Order both property sequences to preserve reflexivity.
foreach (var propertyComp in x.Properties().OrderBy(p => p.Name).Zip(y.Properties().OrderBy(p => p.Name), (xp, yp) => JTokenComparer.Instance.Compare(xp, yp)))
if (propertyComp != 0)
return propertyComp;
if ((comp = x.Count.CompareTo(y.Count)) != 0)
return comp;
return 0;
}
}
class JArrayComparer : JContainerOrderedComparerBase<JArray>
{
protected override int CompareDerived(JArray x, JArray y)
{
int comp;
if ((comp = CompareItemsInOrder(x, y)) != 0)
return comp;
return 0;
}
}
class JConstructorComparer : JContainerOrderedComparerBase<JConstructor>
{
protected override int CompareDerived(JConstructor x, JConstructor y)
{
int comp;
if ((comp = x.Name.CompareTo(y.Name)) != 0)
return comp;
if ((comp = CompareItemsInOrder(x, y)) != 0)
return comp;
return 0;
}
}
class JValueComparer : JTokenComparerBase<JValue>
{
protected override int CompareDerived(JValue x, JValue y)
{
return Comparer<JToken>.Default.Compare(x, y); // JValue implements IComparable<JValue>
}
}
Lightly tested prototype fiddle.
This could, actually, be done with less code. Not as nice, because using string comparison instead of JValue comparison.
Following is not an exact answer to my own question, but the goal is achieved.
public static JToken Normalize(this JToken token)
{
var result = token;
switch (token.Type)
{
case JTokenType.Object:
var jObject = (JObject)token;
if (jObject != null && jObject.HasValues)
{
var newObject = new JObject();
foreach (var property in jObject.Properties().OrderBy(x => x.Name).ToList())
{
var value = property.Value as JToken;
if (value != null)
{
value = Normalize(value);
}
newObject.Add(property.Name, value);
}
return newObject;
}
break;
case JTokenType.Array:
var jArray = (JArray)token;
if (jArray != null && jArray.Count > 0)
{
var normalizedArrayItems = jArray
.Select(x => Normalize(x))
.OrderBy(x => x.ToString(), StringComparer.Ordinal);
result = new JArray(normalizedArrayItems);
}
break;
default:
break;
}
return result;
}

C# Extend array type to overload operators

I'd like to create my own class extending array of ints. Is that possible? What I need is array of ints that can be added by "+" operator to another array (each element added to each), and compared by "==", so it could (hopefully) be used as a key in dictionary.
The thing is I don't want to implement whole IList interface to my new class, but only add those two operators to existing array class.
I'm trying to do something like this:
class MyArray : Array<int>
But it's not working that way obviously ;).
Sorry if I'm unclear but I'm searching solution for hours now...
UPDATE:
I tried something like this:
class Zmienne : IEquatable<Zmienne>
{
public int[] x;
public Zmienne(int ilosc)
{
x = new int[ilosc];
}
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
return base.Equals((Zmienne)obj);
}
public bool Equals(Zmienne drugie)
{
if (x.Length != drugie.x.Length)
return false;
else
{
for (int i = 0; i < x.Length; i++)
{
if (x[i] != drugie.x[i])
return false;
}
}
return true;
}
public override int GetHashCode()
{
int hash = x[0].GetHashCode();
for (int i = 1; i < x.Length; i++)
hash = hash ^ x[i].GetHashCode();
return hash;
}
}
Then use it like this:
Zmienne tab1 = new Zmienne(2);
Zmienne tab2 = new Zmienne(2);
tab1.x[0] = 1;
tab1.x[1] = 1;
tab2.x[0] = 1;
tab2.x[1] = 1;
if (tab1 == tab2)
Console.WriteLine("Works!");
And no effect. I'm not good with interfaces and overriding methods unfortunately :(. As for reason I'm trying to do it. I have some equations like:
x1 + x2 = 0.45
x1 + x4 = 0.2
x2 + x4 = 0.11
There are a lot more of them, and I need to for example add first equation to second and search all others to find out if there is any that matches the combination of x'es resulting in that adding.
Maybe I'm going in totally wrong direction?
For a single type, it is pretty easy to encapsulate, as below. Note that as a key you want to make it immutable too. If you want to use generics, it gets harder (ask for more info):
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
static class Program {
static void Main() {
MyVector x = new MyVector(1, 2, 3), y = new MyVector(1, 2, 3),
z = new MyVector(4,5,6);
Console.WriteLine(x == y); // true
Console.WriteLine(x == z); // false
Console.WriteLine(object.Equals(x, y)); // true
Console.WriteLine(object.Equals(x, z)); // false
var comparer = EqualityComparer<MyVector>.Default;
Console.WriteLine(comparer.GetHashCode(x)); // should match y
Console.WriteLine(comparer.GetHashCode(y)); // should match x
Console.WriteLine(comparer.GetHashCode(z)); // *probably* different
Console.WriteLine(comparer.Equals(x,y)); // true
Console.WriteLine(comparer.Equals(x,z)); // false
MyVector sum = x + z;
Console.WriteLine(sum);
}
}
public sealed class MyVector : IEquatable<MyVector>, IEnumerable<int> {
private readonly int[] data;
public int this[int index] {
get { return data[index]; }
}
public MyVector(params int[] data) {
if (data == null) throw new ArgumentNullException("data");
this.data = (int[])data.Clone();
}
private int? hash;
public override int GetHashCode() {
if (hash == null) {
int result = 13;
for (int i = 0; i < data.Length; i++) {
result = (result * 7) + data[i];
}
hash = result;
}
return hash.GetValueOrDefault();
}
public int Length { get { return data.Length; } }
public IEnumerator<int> GetEnumerator() {
for (int i = 0; i < data.Length; i++) {
yield return data[i];
}
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
public override bool Equals(object obj)
{
return this == (obj as MyVector);
}
public bool Equals(MyVector obj) {
return this == obj;
}
public override string ToString() {
StringBuilder sb = new StringBuilder("[");
if (data.Length > 0) sb.Append(data[0]);
for (int i = 1; i < data.Length; i++) {
sb.Append(',').Append(data[i]);
}
sb.Append(']');
return sb.ToString();
}
public static bool operator ==(MyVector x, MyVector y) {
if(ReferenceEquals(x,y)) return true;
if(ReferenceEquals(x,null) || ReferenceEquals(y,null)) return false;
if (x.hash.HasValue && y.hash.HasValue && // exploit known different hash
x.hash.GetValueOrDefault() != y.hash.GetValueOrDefault()) return false;
int[] xdata = x.data, ydata = y.data;
if(xdata.Length != ydata.Length) return false;
for(int i = 0 ; i < xdata.Length ; i++) {
if(xdata[i] != ydata[i]) return false;
}
return true;
}
public static bool operator != (MyVector x, MyVector y) {
return !(x==y);
}
public static MyVector operator +(MyVector x, MyVector y) {
if(x==null || y == null) throw new ArgumentNullException();
int[] xdata = x.data, ydata = y.data;
if(xdata.Length != ydata.Length) throw new InvalidOperationException("Length mismatch");
int[] result = new int[xdata.Length];
for(int i = 0 ; i < xdata.Length ; i++) {
result[i] = xdata[i] + ydata[i];
}
return new MyVector(result);
}
}
Its not permitted to extend the array class, see the reference: http://msdn.microsoft.com/en-us/library/system.array.aspx
You could either implement IList (which has the basic methods), or encapsulate an Array in your class and provide conversion operators.
Please let me know if you need more detail.
Can you not just use the List class? This already does what you want via the AddRange method.
implement the ienumerable interface

Categories

Resources