Reputation: 7938
Title says it all. As you can see below, comparing 2 tuples containing equal values for equality returns false
➜ algo-ts git:(master) ✗ ts-node
> const expected: [number, number] = [4, 4];
undefined
> const actual: [number, number] = [4, 4];
undefined
> actual == expected
false
> actual === expected
false
What is the idiomatic way to compare tuples, regardless of the tuples' types?
Upvotes: 2
Views: 5819
Reputation: 4016
When using chai test framework, you can just use the 'deep' module:
let expected = [1, 2, "3"];
let actual = [1, 2, "3"];
// compare by reference => false
expect(expected).to.equal(actual);
// compare by checking values => true
expect(expected).to.deep.equal(actual);
Upvotes: 0
Reputation: 53
A simple approach is to convert them to strings and then compare them.
The benefit with this approach is that you can use these strings in hashed collections like Map<> and Set<>
Example:
let t1 : [number, string] = [1,"test"];
let t2 : [number, string] = [1,"test"];
if (t1.toString() == t2.toString())
console.log("t1 and t2 are equal");
let mySet = new Set<string>();
mySet.add([1,2].toString());
if (mySet.has([1,2].toString()))
console.log("mySet contains tuple [1,2]");
Upvotes: 0
Reputation: 3048
Tuples in TypeScript become just arrays in JavaScript after transpilation. So the question is essentially "How to compare two arrays for equality, where order matters?".
If you're happy to trust your TypeScript typings you could use something like the example below that doesn't bother comparing array length. It also uses a shallow comparison (===
) for simplicity.
const tuplesEqual = <T, U>(x: [T, U], y: [T, U]) => x.every((xVal, i) => xVal === y[i]);
Of course this only works for two-tuples - creating a single function that correctly works for tuples of any length is "more challenging" (I'm not going to say impossible, as you can do a lot with TypeScript generics!)
Upvotes: 0
Reputation: 157
const arrA = [4, 4];
const arrB = [4, 4];
function isEqualsArray(arrA, arrB) {
if (arrA.length != arrB.length) {
return false;
}
let isSameAll = arrA.every((valueA, indexA) => valueA == arrB[indexA]);
return isSameAll;
}
console.log(isEqualsArray(arrA, arrB))
But, The array could have object value, so you need primitive and object equals function.
See more good often source. Like lodash. https://github.com/lodash/lodash/blob/master/.internal/equalArrays.js
Additional contents.
import { isEqualsArray } from './isEqualsArray';
describe('isEqualsArray', () => {
test('number tuples', () => {
const arrA: [number, number] = [4, 4];
const arrB: [number, number] = [4, 4];
expect(isEqualsArray(arrA, arrB)).toBe(true);
});
test('primitive tuples wihout object', () => {
const arrA: [boolean, number] = [false, 4];
const arrB: [boolean, number] = [true, 4];
expect(isEqualsArray(arrA, arrB)).toBe(false);
});
test('primitive tuples wihout object2', () => {
const arrA: [string, number] = ['almel', 4];
const arrB: [string, number] = ['shun', 4];
expect(isEqualsArray(arrA, arrB)).toBe(false);
});
test('primitive tuples wihout object3', () => {
const arrA: [string, number] = ['almel', 1];
const arrB: [string, boolean] = ['almel', true];
expect(isEqualsArray(arrA, arrB)).toBe(true); // because of double equals, so number and boolean are equals
});
// if you think this solution, you don't know js.
test('Double equals', () => {
const arrA: [number, number] = [4, 4];
const arrB: [number, number] = [4, 4];
expect(arrA == arrB).toBe(false);
});
});
I tested my codes with ts-jest. These tests are passed all. javascript deosn't have tuple types... This is array in javascript world.
Upvotes: 0
Reputation: 1121
That is because you are comparing your tuples references and not the equality of each value.
As long as your tuples only contain primitives you could do something like:
equals(expected:[number,number],actual:[number,number]): boolean{
return expected[0] === actual[0] && expected[1] === actual[1];
}
But if you wan't to compare tuples with objects you would need to define such an equals function for your objects as well.
It depends on the specific type how an equals method should be implemented and therefore there is no "silver bullet" for object equality.
Upvotes: 1