How to Compare "Any" Value Types

How to compare Any value types

The only way to do this is with a function other than == that takes a type parameter, and then compares the values if they are both of that type:

func isEqual<T: Equatable>(type: T.Type, a: Any, b: Any) -> Bool {
guard let a = a as? T, let b = b as? T else { return false }

return a == b
}

Now, using your variables above, you can compare them like this:

var any1: Any = 1
var any2: Any = 1

var any3: Any = "test"
var any4: Any = "test"

isEqual(type: Int.self, a: any1, b: any2) // true
isEqual(type: Int.self, a: any2, b: any3) // false
isEqual(type: String.self, a: any3, b: any4) // true

Comparing boxed values of different types

I suggest to use dynamic for that task.

object o1 = 2m;
object o2 = 2L;

if ((dynamic)o1 == (dynamic)o2) { Console.WriteLine("Works like charm"); }

Yet, I am not fully aware of all implications of dynamic keyword, so take care!

Comparing VALUE and REFERENCE of types

Equals and == will compare by reference by default if they're not overriden / overloaded in a subclass. ReferenceEquals will always compare by reference.

Strings are a confusing data type to use for experimenting with this, because they overload == to implement value equality; also, since they're immutable, C# will generally reuse the same instance for the same literal string. In your code, str and str2 will be the same object.

How to compare two types JavaScript?

To compare two types in javascript, use typeof.

(function () {
var a = [];
var b = [];
var c = a;

var d = "a";
var e = "a";

console.log(typeof(a) == typeof(b));
console.log(typeof(a) == typeof(c));
console.log(typeof(d) == typeof(e));
})();

How to check equality of boxed object of value types when types are different but compatible to compare the values

The type of the variable is kept in object.

For example:

Console.Write(ob_a.GetType().ToString());   // will give you System.Int32
Console.Write(ob_b.GetType().ToString()); // will give you System.Int16

It gives different hash codes also with method: GetHashCode()

If you will convert short variable to int or the other way, it will be equal... So basically the problem is with different variable types.

Here is the answer for both questions: http://www.ikriv.com/dev/dotnet/ObjectEquality.html

Since call to Equals() is virtual, exact version of the method that will be called by x.Equals(y) is determined by dynamic type of x, that usually is not known at compile time. Note also, that unlike a==b, expression x.Equals(y) is inherently asymmetrical. Only x dictates what version of Equals() will be called. y has absolutely no say in the matter.

How to compare type of an object in Python?

isinstance()

In your case, isinstance("this is a string", str) will return True.

You may also want to read this: http://www.canonical.org/~kragen/isinstance/

What are the general rules for comparing different data types in C?

This is governed by the usual arithmetic conversions. For simple cases, the general rule of thumb is that the type with "less" precision is converted to match the type with "more" precision, but it gets somewhat complex once you start mixing signed and unsigned.

In C99, this is described by section 6.3.1.8, which I include here for your convenience:

  • First, if the corresponding real type of either operand is long double,
    the other operand is converted,
    without change of type domain, to a
    type whose corresponding real type is
    long double.

  • Otherwise, if the corresponding real type of either operand is double,
    the other operand is converted,
    without change of type domain, to a
    type whose corresponding real type is
    double.

  • Otherwise, if the corresponding real type of either operand is float,
    the other operand is converted,
    without change of type domain, to a
    type whose corresponding real type is
    float.

  • Otherwise, the integer promotions are performed on both operands. Then
    the following rules are applied to the
    promoted operands:

    • If both operands have the same type, then no further conversion is
      needed.
    • Otherwise, if both operands have signed integer types or both have
      unsigned integer types, the operand
      with the type of lesser integer
      conversion rank is converted to the
      type of the operand with greater rank.
    • Otherwise, if the operand that has unsigned integer type has rank
      greater or equal to the rank of the
      type of the other operand, then the
      operand with signed integer type is
      converted to the type of the operand
      with unsigned integer type.
    • Otherwise, if the type of the operand with signed integer type can
      represent all of the values of the
      type of the operand with unsigned
      integer type, then the operand with
      unsigned integer type is converted to
      the type of the operand with signed
      integer type.
    • Otherwise, both operands are converted to the unsigned integer type
      corresponding to the type of the
      operand with signed integer type.

I've highlighted the part that applies to your particular example.

The concept of integer conversion rank is defined in section 6.3.1.1, and it basically describes what you might expect (that types with less precision have a lower rank than types with more precision).

Java: comparing two Objects of different type with same value, returning true

Here is a method for doing exactly the comparison described in the edited question.

/**
* Compare objects for equal value, with some disregard for type.
* <p>
* The following types are considered similar, for the purpose of comparing values. The
* values of the secondary types are converted to the first listed type for value comparison.
* <ul>
* <li>{@code long}, {@code int}, {@code short}</li>
* <li>{@code double} <i>(rounded to 3 decimals before comparing)</i></li>
* <li>{@code String}, {@code Timestamp}</li>
* <li>Array <i>(elements are compared using this method, comparison is "deep")</i></li>
* </ul>
* Values for all other types are only considered equal if they have the exact same type
* and {@code equals()} return {@code true}.
*
* @param obj1 the first object to be compared.
* @param obj2 the second object to be compared.
* @return {@code true} only if the specified objects are equals according to the rules listed above.
*/
public static boolean equalValue(Object obj1, Object obj2) {
// Compare null values
if (obj1 == null)
return (obj2 == null);
if (obj2 == null)
return false;

Class<?> class1 = obj1.getClass();
Class<?> class2 = obj2.getClass();

// Compare double values, rounded to 3 decimal places
if (class1 == Double.class && class2 == Double.class) {
// Can't use Math.round() because it doesn't do round-half-up, and may overflow long value-range
BigDecimal dec1 = BigDecimal.valueOf(((Number)obj1).doubleValue()).setScale(3, RoundingMode.HALF_UP);
BigDecimal dec2 = BigDecimal.valueOf(((Number)obj2).doubleValue()).setScale(3, RoundingMode.HALF_UP);
return dec1.equals(dec2); // equals() is ok, since we know they have same scale
}

// Compare arrays
if (class1.isArray() && class2.isArray()) {
int len = Array.getLength(obj1);
if (len != Array.getLength(obj2))
return false;
for (int i = 0; i < len; i++)
if (! equalValue(Array.get(obj1, i), Array.get(obj2, i)))
return false;
return true;
}

// Now that special cases are done, apply simple comparison for values of same type
if (class1 == class2)
return obj1.equals(obj2);

// Compare long/int/short values
if ((class1 == Long.class || class1 == Integer.class || class1 == Short.class) &&
(class2 == Long.class || class2 == Integer.class || class2 == Short.class)) {
return ((Number)obj1).longValue() == ((Number)obj2).longValue();
}

// Compare String/Timestamp values
if ((class1 == String.class || obj1 instanceof Timestamp) &&
(class2 == String.class || obj2 instanceof Timestamp)) {
return obj1.toString().equals(obj2.toString());
}

return false; // Incomparable types
}


Related Topics



Leave a reply



Submit