Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript: Avoid comparison by reference

I need to store a list of points and check if a new point is already included in that list

class Point {
    x: number;
    y: number;
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }
}

window.onload = () => {
    var points : Point[] = [];
    points.push(new Point(1,1));
    var point = new Point(1,1);
    alert(points.indexOf(point)); // -1 
}

Obviously typescript uses comparison by reference but in this case that doesn't make sense. In Java or C# I would overload the equals method, in typescript that doesn't seem to be possible.

I considered to loop through the array with foreach and check each entry for equality, but that seems rather complicated and would bloat the code.

Is there something like equals in typescript ? How can I implement my own comparisons ?

like image 344
lhk Avatar asked Jan 28 '14 13:01

lhk


1 Answers

You could wrap the collection in a PointList that only allows Point objects to be added via an add method, which checks to ensure no duplicates are added.

This has the benefit of encapsulating the "No duplicates" rule in a single place, rather than hoping that all calling code will check before adding a duplicate, which would duplicate the rule in many places.

class Point {
    constructor(public x: number, public y: number) {
    }
}

class PointList {
    private points: Point[] = [];

    get length() {
        return this.points.length;
    }

    add(point: Point) {
        if (this.exists(point)) {
            // throw 'Duplicate point';
            return false;
        }

        this.points.push(point);
        return true;
    }

    exists(point: Point) {
        return this.findIndex(point) > -1;
    }

    findIndex(point: Point) {
        for (var i = 0; i < this.points.length; i++) {
            var existingPoint = this.points[i];
            if (existingPoint.x === point.x && existingPoint.y === point.y) {
                return i;
            }
        }

        return -1;
    }
}

var pointList = new PointList();

var pointA = new Point(1, 1);
var pointB = new Point(1, 1);
var pointC = new Point(1, 2);

pointList.add(pointA);
alert(pointList.length); // 1

pointList.add(pointB);
alert(pointList.length); // 1

pointList.add(pointC);
alert(pointList.length); // 2
like image 160
Fenton Avatar answered Oct 17 '22 18:10

Fenton