I have a Set<Point<double>> and I want to test if the set contains a particular Point<double>.
My understanding is that if two Point<double> instances have the same hashCode and are equal according to ==, then the default Set implementation considers them identical and will return true when one of the points is in the set and we test for the other using contains.
But in the following example this doesn't seem to be the case:
import 'dart:math';
void main() {
final points = Set<Point<double>>.identity();
final a = Point<double>(5, 2);
final b = Point<double>(5, 2);
points.add(a);
print("a == b ? ${a == b}");
print("a.hashCode == b.hashCode ? ${a.hashCode == b.hashCode}");
print("points.contains(a) ? ${points.contains(a)}");
print("points.contains(b) ? ${points.contains(b)}");
}
According to DartPad the output is:
a == b ? true
a.hashCode == b.hashCode ? true
points.contains(a) ? true
points.contains(b) ? false
Where have I gone wrong here?
Set<Point<double>>.identity() uses idenity hash for comparing. But Point has overriden comparsion by equality of x and y (See source code)
So in this case a.idenityHash != a.hashcode and a.idenityHash != b.idenityHash even if a.hashCode == b.hashCode. This all happend because == and hashCode were overriden for object compararsion by coordinates.
So if you create normal set, which is using hashCode methods for comparsion, you get expected result
final points = Set<Point<double>>();
points.add(a);
print("points.contains(b) ? ${points.contains(b)}"); // true
This happens because thay are not identical but you specified to compare them by identity instead of equilvalence.
import 'dart:math';
void main() {
//final points = Set<Point<double>>.identity();
final points = Set<Point<double>>();
final a = Point<double>(5, 2);
final b = Point<double>(5, 2);
points.add(a);
print("a == b ? ${a == b}");
print("a.hashCode == b.hashCode ? ${a.hashCode == b.hashCode}");
print("points.contains(a) ? ${points.contains(a)}");
print("points.contains(b) ? ${points.contains(b)}");
}
You disabled this operator.
/**
* A `Point` is only equal to another `Point` with the same coordinates.
*
* This point is equal to `other` if, and only if,
* `other` is a `Point` with
* [x] equal to `other.x` and [y] equal to `other.y`.
*/
bool operator ==(dynamic other) =>
// Cannot change parameter type to `Object` in case some class
// inherits the type and uses their argument dynamically.
other is Point && x == other.x && y == other.y;
This is explains this in details (use equals: identical).
/**
* Creates an insertion-ordered identity-based set.
*
* Effectively a shorthand for:
*
* new LinkedHashSet<E>(equals: identical,
* hashCode: identityHashCode)
*/
external factory LinkedHashSet.identity();
Related
I have noticed the operator ^ in dart which never seen before.
Its being use in calculating the hashcode see below for details.
Here is a code snippet, check the section hashcode where i saw:
import './color.dart';
import './colors.dart';
class CoreState {
final int counter;
final Color backgroundColor;
const CoreState({
this.counter = 0,
this.backgroundColor = Colors.white,
});
CoreState copyWith({
int? counter,
Color? backgroundColor,
}) =>
CoreState(
counter: counter ?? this.counter,
backgroundColor: backgroundColor ?? this.backgroundColor,
);
#override
bool operator ==(Object other) =>
identical(this, other) ||
other is CoreState &&
runtimeType == other.runtimeType &&
counter == other.counter &&
backgroundColor == other.backgroundColor;
#override
int get hashCode => counter.hashCode ^ backgroundColor.hashCode;
#override
String toString() {
return "counter: $counter\n"
"color:$backgroundColor";
}
}
The Dart Language Tour explains that ^ is bitwise XOR. This operator is typically used for computing hash codes. For an explanation why see Why is XOR often used in Java hascode...
The ^ operator in Dart stand for XOR.
For more details, check this
In Dart, the ^ operator is a user-definable operator.
The traditional use of it is exclusive-or (XOR) of integers and Booleans.
var x = 170;
x = x ^ 85;
print(x); // 255;
x ^= 85; // Same meaning as `x = x ^ 85;`.
print(x); // 170
and
var oddity = false;
for (var number in someNumbers) {
oddity ^= element.isOdd;
}
// True if an odd number of numbers are odd.
You can implement the ^ operator on your own classes too. For example the BigInt and Int32x4 classes do, with similar XOR-based meaning.
You could also use it for different things, say matrix exponentiation:
class Matrix {
// ...
Matrix operator ^(int power) {
RangeError.checkNotNegative(power, "power");
if (this.height != this.width) {
throw UnsupportedError("Can only do exponents of square matrices");
}
var result = Matrix.identity(this.height);
while (power > 0) { // Can be made more efficient!
result *= this;
power -= 1;
}
return result;
}
}
...
var matrix = otherMatrix ^ 2;
The precedence of the operator is always the same (just between & and |).
num point = 100;
bool fail = (point < 75) ? true : false;
print(fail); // false
point = 50;
print(fail); // false
I've changed point values but why fail doesn't change it values? although it satisfied the condition.
Please help me describe this problem
Thanks.
The reason is the value of fail (the variable) are being evaluated at the point of declaration. So we are calculating (point < 75) ? true : false and the value are saved into the variable of fail.
The variable is therefore not defined as a function but instead a specific value at the given time it was defined.
If you instead want fail to be defined as a method which can be evaluated multiple times you can do something like this:
void main() {
num point = 100;
bool Function() fail = () => (point < 75) ? true : false;
print(fail()); // false
point = 50;
print(fail()); // true
}
Normally you want to pack this kind of logic inside a class like this:
class OurClass {
num point;
OurClass(this.point);
bool get fail => (point < 75) ? true : false;
}
void main() {
OurClass oClass = OurClass(100);
print(oClass.fail); // false
oClass.point = 50;
print(oClass.fail); // true
}
So here we can define a get method which act like a variable but where we can evaluate the value each time we try to get it. So here we can define fail as the value returned from evaluating (point < 75) ? true : false;.
The program works fine with var dig = 0 and it doesn't work with var dig:Int I get an error: Variable "dig" used before being initialized Could you explain me why?
func myFunc(a:Int, b:Int) {
var c = a / b
var o = a % b
var v = 0
var dig = 0
if o != 0 {println("\(a)/\(b) = \(c) и \(o)/\(b)")}
else {println("\(a)/\(b) = \(c)")}
if a > b {
v = b
}
else {
v = a
}
for var i = 1; i <= v; ++i {
if a % i == 0 && b % i == 0 {dig = i}
}
println("\(dig) - greatest common denominator of \(a) and \(b)")
}
myFunc(27,81)
The only place you set the value of dig is inside of an if statement that is inside of a for loop. The Swift compiler does not know if the body of the for loop will be executed, and it doesn't know if the if statement will ever be true, so it has to assume that there is a path in which dig is not initialized.
Consider this simpler example:
func myFunc(a:Int, b:Int) {
var dig: Int
if a >= b {
dig = 3
}
if a < b {
dig = 4
}
println("\(dig) - greatest common denominator of \(a) and \(b)")
}
This example also gives the same error, because Swift considers each if separately. It is obvious to us that a is either greater than or equal to b or it is less than b, but Swift doesn't go that far in evaluating the situation. It just considers that each if may not be true, and dig is only set inside of ifs, so it is possible (as far as Swift is concerned) that dig may not be set.
func myFunc(a:Int, b:Int) {
var dig: Int
if a >= b {
dig = 3
} else {
dig = 4
}
println("\(dig) - greatest common denominator of \(a) and \(b)")
}
If you change the second condition to an else, Swift is then happy because it can reason that the if must be true or false and dig is set in each path, so it will certainly have a value before the println statement.
The compiler does not know mathematics good enough to
recognize that the statement
if a % i == 0 && b % i == 0 {dig = i}
is actually executed at least once (for i == 1). Therefore
the compiler assumes that dig might be undefined at
println("\(dig) - greatest common denominator of \(a) and \(b)")
Assigning an initial value in
var dig = 0
is the correct solution.
Btw., the Euclidean Algorithm is a much more effective method to
compute the greatest common divisor, see for example
http://rosettacode.org/wiki/Greatest_common_divisor#Swift.
Is there a simple way to set all values in a cv::Mat to a given value if they fulfill some condition. For instance, I have CV_32FC1, and I want set all values which are 0 to 20. In MATLAB I would have simply done this:
M(M == 0) = 20;
You can use
cv::Mat mask = M == 0;
M.setTo(0.5, mask);
However, it includes using additional memory for creating mask, but is a solution using opencv API therefore can be applied to all matrix types. If you consider performance issues, you can always refer directly to Mat::data to optimize this solution for concrete matrix type.
This is a classic case for look-up table. It is fast, simple, and can remap multiple values at same time.
Thanks to #marol 's comments, I settled for the implementation below. I am using C++11 lambda functions to condition which values need to be changed. To demonstrate its power, my condition is to set to DEFAULT_VAL when the value is out of the range [MIN_VAL, MAX_VAL]:
#include <functional>
#define MatType float
#define MatCmpFunc std::function<bool(const MatType&)>
.
.
.
// function which accepts lambda function to condition values which need to
// be changed
void MatSetIf(cv::Mat& inputmat, const MatType& newval, MatCmpFunc func) {
float* pmat = (float*)inputmat.data;
// iterate and set only values which fulfill the criteria
for (int idx = 0; idx < inputmat.total(); ++idx) {
if (func(pmat[idx])) {
pmat[idx] = newval;
}
}
}
.
.
.
void main() {
cv::Mat mymat(100,100,CV_32FC1);
const float MIN_VAL = 10;
const float MAX_VAL = 1000;
const float DEFAULT_VAL = -1;
.
.
.
// declare lambda function which returns true when mat value out of range
MatCmpFunc func = [&](const DepthMatType& val) -> bool {
return (val < MIN_VAL || val > MAX_VAL) ? true : false;
};
// use lambda func above to set all out of range values to 50
Mat32FSetIf(mymat, DEFAULT_VAL, func);
.
.
.
}
I want to overload the the comparison operator (==) in Dart to compare structures. Now I'm not sure how to do this for derived classes when I already have overloaded the comparison operator of the base class and want to reuse that.
Assuming I have a a base class like:
class Base
{
int _a;
String _b;
bool operator ==(Base other)
{
if (identical(other, this)) return true;
if (_a != other._a) return false;
if (_b != other._b) return false;
return true;
}
}
Then I declare I derived class that adds additional fields and also want to overload operator==. I only want to compare the additional fields in the derived class and delegate the comparison of Base fields to the Base class. In other programming languages I could do something like Base::operator==(other) or super.equals(other), but in Dart I can't figure out what's the best way to do it.
class Derived extends Base
{
int _c; // additional field
bool operator ==(Derived other)
{
if (identical(other, this)) return true;
if (_c != other._c) return false; // Comparison of new field
// The following approach gives the compiler error:
// Equality expression cannot be operand of another equality expression.
if (!(super.==(other))) return false;
// The following produces "Unnecessary cast" warnings
// It also only recursively calls the Derived operator
if ((this as Base) != (other as Base)) return false;
return true;
}
}
I guess what I could do is:
Compare all fields of base class also in the derived class: Is very error prone if base class get's changed and also doesn't work when base and derived are in different packages.
Declare an equals function with the same logic as currently operator == in it, call super.equals() to compare the base class and delegate all calls of operator== to the equals function. However it doesn't look too appealing to implement equals and operator ==.
So what's the best or recommended solution for this problem?
Ok, after some further experiments I figured it out on my own.
It's simply calling:
super==(other)
I tried it with super.operator==(other) and super.==(other) before, but didn't expect that the simple super==(other) is sufficient.
For the given example above the correct operator is:
bool operator ==(Derived other)
{
if (identical(other, this)) return true;
if (_c != other._c) return false;
if (!(super==(other))) return false;
return true;
}
Seems I am bumping a 5 year old question, but since now we have Dart 2...
the == operator can easily be defined inline.
class Base {
int a;
String b;
bool operator ==(other) => other is Base
&& other.a == a
&& other.b == b;
}
To reuse from a derived class, super == other still seems to be the way.
class Derived extends Base {
int c;
bool operator ==(other) => other is Derived
&& super == other
&& other.c == c;
}
Now this being said I discovered a major gotcha, the == operator that is called seems to be that of the left side of the comparision. That is Base == Derived will call Base's == comparision, while Derived == Base will call call Derived's == comparison (and subsequently Base's). This does seem reasonable, but had me scratching my head for a minute.
Ex:
main() {
Base b = new Base();
Derived d1 = new Derived();
Derived d2 = new Derived();
b.a = 6;
d1.a = 6;
d2.a = 6;
b.b = "Hi";
d1.b = "Hi";
d2.b = "Hi";
d1.c = 1;
d2.c = 1;
assert(d1 == d2); // pass
assert(b == d1); // PASS!!!
assert(d1 == b); // fail
}
(Note: I removed the private _'s from the fields for demonstration purposes.)
To avoid the issue where a base class incorrectly has equality with a child clase you can add the additional check for runtimeType as follows.
bool operator ==(other) => other is Base
&& this.runtimeType == other.runtimeType
&& other.a == a
&& other.b == b;