mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-25 15:07:57 +00:00
Back to compareNatural WIP (see #837)
This commit is contained in:
parent
08695ef1c7
commit
0557e7ae1f
@ -5,7 +5,7 @@ module.exports = {
|
||||
'compareNatural(x, y)'
|
||||
],
|
||||
'description':
|
||||
'Compare two values in a natural way. For numeric values, returns 1 if x is larger than y, -1 if x is smaller than y, and 0 if x and y are equal. Strings and complex numbers are compared in a natural way.',
|
||||
'Compare two values in a natural way.',
|
||||
'examples': [
|
||||
'compare(2, 3)',
|
||||
'compare(3, 2)',
|
||||
|
||||
@ -8,7 +8,7 @@ function factory (type, config, load, typed) {
|
||||
var compareDesc = function (a, b) {
|
||||
return -compareAsc(a, b);
|
||||
};
|
||||
var deepStrictCompare = load(require('../relational/deepStrictCompare'));
|
||||
var compareNatural = load(require('../relational/compareNatural'));
|
||||
|
||||
/**
|
||||
* Sort the items in a matrix.
|
||||
@ -33,7 +33,7 @@ function factory (type, config, load, typed) {
|
||||
* filter, forEach, map, compare, compareNatural
|
||||
*
|
||||
* @param {Matrix | Array} x A one dimensional matrix or array to sort
|
||||
* @param {Function | 'asc' | 'desc' | 'deep'} [compare='asc']
|
||||
* @param {Function | 'asc' | 'desc' | 'natural'} [compare='asc']
|
||||
* An optional _comparator function or name. The function is called as
|
||||
* `compare(a, b)`, and must return 1 when a > b, -1 when a < b,
|
||||
* and 0 when a == b.
|
||||
@ -74,8 +74,8 @@ function factory (type, config, load, typed) {
|
||||
sort.toTex = undefined; // use default template
|
||||
|
||||
/**
|
||||
* Get the comparator for given order ('asc', 'desc', 'deep')
|
||||
* @param {'asc' | 'desc' | 'deep'} order
|
||||
* Get the comparator for given order ('asc', 'desc', 'natural')
|
||||
* @param {'asc' | 'desc' | 'natural'} order
|
||||
* @return {Function} Returns a _comparator function
|
||||
*/
|
||||
function _comparator (order) {
|
||||
@ -85,11 +85,11 @@ function factory (type, config, load, typed) {
|
||||
else if (order === 'desc') {
|
||||
return compareDesc;
|
||||
}
|
||||
else if (order === 'deep') {
|
||||
return deepStrictCompare;
|
||||
else if (order === 'natural') {
|
||||
return compareNatural;
|
||||
}
|
||||
else {
|
||||
throw new Error('String "asc", "desc", or "deep" expected');
|
||||
throw new Error('String "asc", "desc", or "natural" expected');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
var naturalSort = require('javascript-natural-sort');
|
||||
var isCollection = require('../../utils/collection/isCollection');
|
||||
|
||||
function factory (type, config, load, typed) {
|
||||
var getTypeOf = load(require('../utils/typeof'));
|
||||
var isNumeric = load(require('../utils/isNumeric'));
|
||||
var matrix = load(require('../../type/matrix/function/matrix'));
|
||||
var compare = load(require('./compare'));
|
||||
|
||||
@ -30,24 +32,24 @@ function factory (type, config, load, typed) {
|
||||
*
|
||||
* Syntax:
|
||||
*
|
||||
* math.deepStrictCompare(x, y)
|
||||
* math.compareNatural(x, y)
|
||||
*
|
||||
* Examples:
|
||||
*
|
||||
* math.deepStrictCompare(6, 1); // returns 1
|
||||
* math.deepStrictCompare(2, 3); // returns -1
|
||||
* math.deepStrictCompare(7, 7); // returns 0
|
||||
* math.compareNatural(6, 1); // returns 1
|
||||
* math.compareNatural(2, 3); // returns -1
|
||||
* math.compareNatural(7, 7); // returns 0
|
||||
*
|
||||
* var a = math.unit('5 cm');
|
||||
* var b = math.unit('40 mm');
|
||||
* math.deepStrictCompare(a, b); // returns 1
|
||||
* math.compareNatural(a, b); // returns 1
|
||||
*
|
||||
* var c = math.complex('2 + 3i');
|
||||
* var d = math.complex('2 + 4i');
|
||||
* math.deepStrictCompare(c, d); // returns -1
|
||||
* math.compareNatural(c, d); // returns -1
|
||||
*
|
||||
* math.deepStrictCompare([1, 2, 3], [1, 2]); // returns 1
|
||||
* math.deepStrictCompare([1, 2], [1, 2]); // returns 0
|
||||
* math.compareNatural([1, 2, 3], [1, 2]); // returns 1
|
||||
* math.compareNatural([1, 2], [1, 2]); // returns 0
|
||||
*
|
||||
* See also:
|
||||
*
|
||||
@ -57,7 +59,7 @@ function factory (type, config, load, typed) {
|
||||
* @param {*} y Second value to compare
|
||||
* @return {number} Returns the result of the comparison: 1, 0 or -1.
|
||||
*/
|
||||
var deepStrictCompare = typed('deepStrictCompare', {
|
||||
var compareNatural = typed('compareNatural', {
|
||||
'any, any': function (x, y) {
|
||||
var typeX = getTypeOf(x);
|
||||
var typeY = getTypeOf(y);
|
||||
@ -65,9 +67,11 @@ function factory (type, config, load, typed) {
|
||||
// in case of different types, order by name of type
|
||||
// i.e. 'BigNumber' < 'Complex'
|
||||
if (typeX !== typeY) {
|
||||
return compareString(typeX, typeY);
|
||||
return naturalSort(typeX, typeY);
|
||||
}
|
||||
|
||||
// FIXME: compare all numeric types first by value and then by type
|
||||
|
||||
if (typeX === 'number') {
|
||||
return compareNumbers(x, y);
|
||||
}
|
||||
@ -77,7 +81,7 @@ function factory (type, config, load, typed) {
|
||||
}
|
||||
|
||||
if (typeX === 'Fraction') {
|
||||
return compareFractions(x, y);
|
||||
return compareFractions(x, y).valueOf();
|
||||
}
|
||||
|
||||
if (typeX === 'Complex') {
|
||||
@ -85,8 +89,12 @@ function factory (type, config, load, typed) {
|
||||
}
|
||||
|
||||
if (typeX === 'Unit') {
|
||||
// FIXME: implement ordering for units with different base
|
||||
return compareUnits(x, y);
|
||||
if (x.equalBase(y)) {
|
||||
return compareNatural(x.value, y.value);
|
||||
}
|
||||
|
||||
// compare by units
|
||||
return compareArrays(x.formatUnits(), y.formatUnits());
|
||||
}
|
||||
|
||||
if (typeX === 'boolean') {
|
||||
@ -94,13 +102,14 @@ function factory (type, config, load, typed) {
|
||||
}
|
||||
|
||||
if (typeX === 'string') {
|
||||
return compareString(x, y);
|
||||
return naturalSort(x, y);
|
||||
}
|
||||
|
||||
// FIXME: compare matrices and arrays first by their values and then by type
|
||||
if (typeX === 'Matrix') {
|
||||
// can be SparseMatrix or DenseMatrix
|
||||
if (x.type !== y.type) {
|
||||
return compareString(x.type, y.type)
|
||||
return naturalSort(x.type, y.type)
|
||||
}
|
||||
if (x.type === 'DenseMatrix') {
|
||||
return compareDenseMatrices(x, y);
|
||||
@ -131,7 +140,7 @@ function factory (type, config, load, typed) {
|
||||
}
|
||||
});
|
||||
|
||||
deepStrictCompare.toTex = undefined; // use default template
|
||||
compareNatural.toTex = undefined; // use default template
|
||||
|
||||
/**
|
||||
* Compare two Arrays
|
||||
@ -150,7 +159,7 @@ function factory (type, config, load, typed) {
|
||||
|
||||
// compare each value
|
||||
for (var i = 0; i < a.length; i++) {
|
||||
var v = deepStrictCompare(a[i], b[i]);
|
||||
var v = compareNatural(a[i], b[i]);
|
||||
if (v !== 0) {
|
||||
return v;
|
||||
}
|
||||
@ -230,8 +239,8 @@ function factory (type, config, load, typed) {
|
||||
if (keysA.length < keysB.length) { return -1; }
|
||||
|
||||
// compare keys
|
||||
keysA.sort(compareString)
|
||||
keysB.sort(compareString)
|
||||
keysA.sort(naturalSort)
|
||||
keysB.sort(naturalSort)
|
||||
var c = compareArrays(keysA, keysB);
|
||||
if (c !== 0) {
|
||||
return c;
|
||||
@ -239,7 +248,7 @@ function factory (type, config, load, typed) {
|
||||
|
||||
// compare values
|
||||
for (var i = 0; i < keysA.length; i++) {
|
||||
var v = deepStrictCompare(a[keysA[i]], b[keysB[i]]);
|
||||
var v = compareNatural(a[keysA[i]], b[keysB[i]]);
|
||||
if (v !== 0) {
|
||||
return v;
|
||||
}
|
||||
@ -248,17 +257,7 @@ function factory (type, config, load, typed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return deepStrictCompare;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two strings by the char code of their characters
|
||||
* @param {string} a
|
||||
* @param {string} b
|
||||
* @return {number}
|
||||
*/
|
||||
function compareString (a, b) {
|
||||
return a > b ? 1 : a < b ? -1 : 0;
|
||||
return compareNatural;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -286,5 +285,5 @@ function compareComplexNumbers (a, b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
exports.name = 'deepStrictCompare';
|
||||
exports.name = 'compareNatural';
|
||||
exports.factory = factory;
|
||||
@ -1,6 +1,6 @@
|
||||
module.exports = [
|
||||
require('./compare'),
|
||||
require('./deepStrictCompare'),
|
||||
require('./compareNatural'),
|
||||
require('./deepEqual'),
|
||||
require('./equal'),
|
||||
require('./larger'),
|
||||
|
||||
@ -7,7 +7,7 @@ function factory (type, config, load, typed) {
|
||||
var matrix = load(require('../../type/matrix/DenseMatrix'));
|
||||
var size = load(require('../matrix/size'));
|
||||
var subset = load(require('../matrix/subset'));
|
||||
var deepStrictCompare = load(require('../relational/deepStrictCompare'));
|
||||
var compareNatural = load(require('../relational/compareNatural'));
|
||||
|
||||
/**
|
||||
* Create the cartesian product of two (multi)sets.
|
||||
@ -35,8 +35,8 @@ function factory (type, config, load, typed) {
|
||||
var result = [];
|
||||
}
|
||||
else {
|
||||
var b1 = flatten(Array.isArray(a1) ? a1 : a1.toArray()).sort(deepStrictCompare);
|
||||
var b2 = flatten(Array.isArray(a2) ? a2 : a2.toArray()).sort(deepStrictCompare);
|
||||
var b1 = flatten(Array.isArray(a1) ? a1 : a1.toArray()).sort(compareNatural);
|
||||
var b2 = flatten(Array.isArray(a2) ? a2 : a2.toArray()).sort(compareNatural);
|
||||
var result = [];
|
||||
for (var i=0; i<b1.length; i++) {
|
||||
for (var j=0; j<b2.length; j++) {
|
||||
|
||||
@ -10,7 +10,7 @@ function factory (type, config, load, typed) {
|
||||
var matrix = load(require('../../type/matrix/DenseMatrix'));
|
||||
var size = load(require('../matrix/size'));
|
||||
var subset = load(require('../matrix/subset'));
|
||||
var deepStrictCompare = load(require('../relational/deepStrictCompare'));
|
||||
var compareNatural = load(require('../relational/compareNatural'));
|
||||
|
||||
/**
|
||||
* Create the difference of two (multi)sets. (Every element of set1, that is not the element of set2.)
|
||||
@ -42,8 +42,8 @@ function factory (type, config, load, typed) {
|
||||
return flatten(a1.toArray());
|
||||
}
|
||||
else {
|
||||
var b1 = identify(flatten(Array.isArray(a1) ? a1: a1.toArray()).sort(deepStrictCompare));
|
||||
var b2 = identify(flatten(Array.isArray(a2) ? a2: a2.toArray()).sort(deepStrictCompare));
|
||||
var b1 = identify(flatten(Array.isArray(a1) ? a1: a1.toArray()).sort(compareNatural));
|
||||
var b2 = identify(flatten(Array.isArray(a2) ? a2: a2.toArray()).sort(compareNatural));
|
||||
var result = [];
|
||||
var inb2;
|
||||
for (var i=0; i<b1.length; i++) {
|
||||
|
||||
@ -8,7 +8,7 @@ function factory (type, config, load, typed) {
|
||||
var matrix = load(require('../../type/matrix/DenseMatrix'));
|
||||
var size = load(require('../matrix/size'));
|
||||
var subset = load(require('../matrix/subset'));
|
||||
var deepStrictCompare = load(require('../relational/deepStrictCompare'));
|
||||
var compareNatural = load(require('../relational/compareNatural'));
|
||||
|
||||
/**
|
||||
* Collect the distinct elements of a multiset.
|
||||
@ -35,7 +35,7 @@ function factory (type, config, load, typed) {
|
||||
var result = [];
|
||||
}
|
||||
else {
|
||||
var b = flatten(Array.isArray(a) ? a : a.toArray()).sort(deepStrictCompare);
|
||||
var b = flatten(Array.isArray(a) ? a : a.toArray()).sort(compareNatural);
|
||||
var result = [];
|
||||
result.push(b[0]);
|
||||
for (var i=1; i<b.length; i++) {
|
||||
|
||||
@ -10,7 +10,7 @@ function factory (type, config, load, typed) {
|
||||
var matrix = load(require('../../type/matrix/DenseMatrix'));
|
||||
var size = load(require('../matrix/size'));
|
||||
var subset = load(require('../matrix/subset'));
|
||||
var deepStrictCompare = load(require('../relational/deepStrictCompare'));
|
||||
var compareNatural = load(require('../relational/compareNatural'));
|
||||
|
||||
/**
|
||||
* Create the intersection of two (multi)sets.
|
||||
@ -39,8 +39,8 @@ function factory (type, config, load, typed) {
|
||||
var result = [];
|
||||
}
|
||||
else {
|
||||
var b1 = identify(flatten(Array.isArray(a1) ? a1 : a1.toArray()).sort(deepStrictCompare));
|
||||
var b2 = identify(flatten(Array.isArray(a2) ? a2 : a2.toArray()).sort(deepStrictCompare));
|
||||
var b1 = identify(flatten(Array.isArray(a1) ? a1 : a1.toArray()).sort(compareNatural));
|
||||
var b2 = identify(flatten(Array.isArray(a2) ? a2 : a2.toArray()).sort(compareNatural));
|
||||
var result = [];
|
||||
for (var i=0; i<b1.length; i++) {
|
||||
for (var j=0; j<b2.length; j++) {
|
||||
|
||||
@ -8,7 +8,7 @@ function factory (type, config, load, typed) {
|
||||
var index = load(require('../../type/matrix/MatrixIndex'));
|
||||
var size = load(require('../matrix/size'));
|
||||
var subset = load(require('../matrix/subset'));
|
||||
var deepStrictCompare = load(require('../relational/deepStrictCompare'));
|
||||
var compareNatural = load(require('../relational/compareNatural'));
|
||||
|
||||
/**
|
||||
* Decide whether a (multi)set is a subset of another (multi)set. (Every element of set1 is the element of set2.)
|
||||
@ -39,8 +39,8 @@ function factory (type, config, load, typed) {
|
||||
else if (subset(size(a2), new index(0)) === 0) { // anything is not a subset of empty
|
||||
return false;
|
||||
}
|
||||
var b1 = identify(flatten(Array.isArray(a1) ? a1 : a1.toArray()).sort(deepStrictCompare));
|
||||
var b2 = identify(flatten(Array.isArray(a2) ? a2 : a2.toArray()).sort(deepStrictCompare));
|
||||
var b1 = identify(flatten(Array.isArray(a1) ? a1 : a1.toArray()).sort(compareNatural));
|
||||
var b2 = identify(flatten(Array.isArray(a2) ? a2 : a2.toArray()).sort(compareNatural));
|
||||
var inb2;
|
||||
for (var i=0; i<b1.length; i++) {
|
||||
inb2 = false;
|
||||
|
||||
@ -6,7 +6,7 @@ function factory (type, config, load, typed) {
|
||||
var index = load(require('../../type/matrix/MatrixIndex'));
|
||||
var size = load(require('../matrix/size'));
|
||||
var subset = load(require('../matrix/subset'));
|
||||
var deepStrictCompare = load(require('../relational/deepStrictCompare'));
|
||||
var compareNatural = load(require('../relational/compareNatural'));
|
||||
|
||||
/**
|
||||
* Create the powerset of a (multi)set. (The powerset contains very possible subsets of a (multi)set.)
|
||||
@ -32,7 +32,7 @@ function factory (type, config, load, typed) {
|
||||
if (subset(size(a), new index(0)) === 0) { // if empty, return empty
|
||||
return [];
|
||||
}
|
||||
var b = flatten(Array.isArray(a) ? a : a.toArray()).sort(deepStrictCompare);
|
||||
var b = flatten(Array.isArray(a) ? a : a.toArray()).sort(compareNatural);
|
||||
var result = [];
|
||||
var number = 0;
|
||||
while (number.toString(2).length <= b.length) {
|
||||
|
||||
@ -4,7 +4,7 @@ var flatten = require('../../utils/array').flatten;
|
||||
|
||||
function factory (type, config, load, typed) {
|
||||
var equal = load(require('../relational/equal'));
|
||||
var deepStrictCompare = load(require('../relational/deepStrictCompare'));
|
||||
var compareNatural = load(require('../relational/compareNatural'));
|
||||
|
||||
/**
|
||||
* Count the number of elements of a (multi)set. When a second parameter is 'true', count only the unique values.
|
||||
@ -35,7 +35,7 @@ function factory (type, config, load, typed) {
|
||||
return Array.isArray(a) ? flatten(a).length : flatten(a.toArray()).length;
|
||||
}
|
||||
else {
|
||||
var b = flatten(Array.isArray(a) ? a : a.toArray()).sort(deepStrictCompare);
|
||||
var b = flatten(Array.isArray(a) ? a : a.toArray()).sort(compareNatural);
|
||||
var count = 1;
|
||||
for (var i=1; i<b.length; i++) {
|
||||
if (!equal(b[i], b[i-1])) {
|
||||
|
||||
@ -6,7 +6,6 @@ function factory (type, config, load, typed) {
|
||||
var index = load(require('../../type/matrix/MatrixIndex'));
|
||||
var concat = load(require('../matrix/concat'));
|
||||
var size = load(require('../matrix/size'));
|
||||
var sort = load(require('../matrix/sort'));
|
||||
var subset = load(require('../matrix/subset'));
|
||||
var setIntersect = load(require('../set/setIntersect'));
|
||||
var setSymDifference = load(require('../set/setSymDifference'));
|
||||
|
||||
@ -28,12 +28,12 @@ exports.type = function(x) {
|
||||
|
||||
if (type === 'object') {
|
||||
if (x === null) return 'null';
|
||||
if (x instanceof Boolean) return 'boolean';
|
||||
if (x instanceof Number) return 'number';
|
||||
if (x instanceof String) return 'string';
|
||||
if (Array.isArray(x)) return 'Array';
|
||||
if (x instanceof Date) return 'Date';
|
||||
if (x instanceof RegExp) return 'RegExp';
|
||||
if (x instanceof Boolean) return 'boolean';
|
||||
if (x instanceof Number) return 'number';
|
||||
if (x instanceof String) return 'string';
|
||||
|
||||
return 'Object';
|
||||
}
|
||||
@ -42,13 +42,3 @@ exports.type = function(x) {
|
||||
|
||||
return type;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether a value is a scalar
|
||||
* @param x
|
||||
* @return {boolean} Returns true when x is a scalar, returns false when
|
||||
* x is a Matrix or Array.
|
||||
*/
|
||||
exports.isScalar = function (x) {
|
||||
return !((x && x.isMatrix) || Array.isArray(x));
|
||||
};
|
||||
|
||||
10
package-lock.json
generated
10
package-lock.json
generated
@ -1883,6 +1883,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"javascript-natural-sort": {
|
||||
"version": "0.7.1",
|
||||
"resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz",
|
||||
"integrity": "sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k="
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.8.4",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.8.4.tgz",
|
||||
@ -2294,11 +2299,6 @@
|
||||
"integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=",
|
||||
"dev": true
|
||||
},
|
||||
"natural-compare": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
|
||||
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc="
|
||||
},
|
||||
"ndarray": {
|
||||
"version": "1.0.18",
|
||||
"resolved": "https://registry.npmjs.org/ndarray/-/ndarray-1.0.18.tgz",
|
||||
|
||||
@ -86,6 +86,7 @@
|
||||
"complex.js": "2.0.4",
|
||||
"decimal.js": "7.2.1",
|
||||
"fraction.js": "4.0.1",
|
||||
"javascript-natural-sort": "0.7.1",
|
||||
"seed-random": "2.2.0",
|
||||
"tiny-emitter": "2.0.0",
|
||||
"typed-function": "0.10.5"
|
||||
|
||||
@ -25,8 +25,8 @@ describe('sort', function() {
|
||||
assert.deepEqual(math.sort([5,10,1], 'desc'), [10,5,1]);
|
||||
});
|
||||
|
||||
it('should deep sort an array', function() {
|
||||
assert.deepEqual(math.sort([{a:4}, {a:2}, {a:3}], 'deep'), [{a:2}, {a:3}, {a:4}]);
|
||||
it('should sort an array naturally', function() {
|
||||
assert.deepEqual(math.sort([{a:4}, {a:2}, {a:3}], 'natural'), [{a:2}, {a:3}, {a:4}]);
|
||||
});
|
||||
|
||||
it('should sort an array with a custom compare function', function() {
|
||||
@ -44,7 +44,7 @@ describe('sort', function() {
|
||||
it('should throw an error if called with unsupported type', function() {
|
||||
assert.throws(function() { math.sort(2) });
|
||||
assert.throws(function() { math.sort('string') });
|
||||
assert.throws(function() { math.sort([], 'string') }, /String "asc", "desc", or "deep" expected/);
|
||||
assert.throws(function() { math.sort([], 'string') }, /String "asc", "desc", or "natural" expected/);
|
||||
assert.throws(function() { math.sort([], {}) });
|
||||
});
|
||||
|
||||
|
||||
221
test/function/relational/compareNatural.test.js
Normal file
221
test/function/relational/compareNatural.test.js
Normal file
@ -0,0 +1,221 @@
|
||||
// test compareNatural
|
||||
var assert = require('assert');
|
||||
var math = require('../../../index');
|
||||
var bignumber = math.bignumber;
|
||||
var complex = math.complex;
|
||||
var matrix = math.matrix;
|
||||
var sparse = math.sparse;
|
||||
var unit = math.unit;
|
||||
var compareNatural = math.compareNatural;
|
||||
|
||||
describe('compareNatural', function() {
|
||||
|
||||
it('should compare two numbers correctly', function() {
|
||||
assert.equal(compareNatural(2, 3), -1);
|
||||
assert.equal(compareNatural(2, 2), 0);
|
||||
assert.equal(compareNatural(2, 1), 1);
|
||||
assert.equal(compareNatural(0, 0), 0);
|
||||
assert.equal(compareNatural(-2, 2), -1);
|
||||
assert.equal(compareNatural(-2, -3), 1);
|
||||
assert.equal(compareNatural(-3, -2), -1);
|
||||
});
|
||||
|
||||
it('should compare two floating point numbers correctly', function() {
|
||||
// Infinity
|
||||
assert.equal(compareNatural(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY), 0);
|
||||
assert.equal(compareNatural(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY), 0);
|
||||
assert.equal(compareNatural(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY), 1);
|
||||
assert.equal(compareNatural(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY), -1);
|
||||
assert.equal(compareNatural(Number.POSITIVE_INFINITY, 2.0), 1);
|
||||
assert.equal(compareNatural(2.0, Number.POSITIVE_INFINITY), -1);
|
||||
assert.equal(compareNatural(Number.NEGATIVE_INFINITY, 2.0), -1);
|
||||
assert.equal(compareNatural(2.0, Number.NEGATIVE_INFINITY), 1);
|
||||
// floating point numbers
|
||||
assert.equal(compareNatural(0.3 - 0.2, 0.1), 0);
|
||||
});
|
||||
|
||||
it('should compare two booleans', function() {
|
||||
assert.equal(compareNatural(true, true), 0);
|
||||
assert.equal(compareNatural(true, false), 1);
|
||||
assert.equal(compareNatural(false, true), -1);
|
||||
assert.equal(compareNatural(false, false), 0);
|
||||
});
|
||||
|
||||
it('should compare bignumbers', function() {
|
||||
assert.strictEqual(compareNatural(bignumber(2), bignumber(3)), -1);
|
||||
assert.strictEqual(compareNatural(bignumber(2), bignumber(2)), 0);
|
||||
assert.strictEqual(compareNatural(bignumber(3), bignumber(2)), 1);
|
||||
assert.strictEqual(compareNatural(bignumber(0), bignumber(0)), 0);
|
||||
assert.strictEqual(compareNatural(bignumber(-2), bignumber(2)), -1);
|
||||
assert.equal(typeof compareNatural(bignumber(-2), bignumber(2)), 'number');
|
||||
});
|
||||
|
||||
it('should compare two fractions', function() {
|
||||
var a = math.fraction(1,3);
|
||||
var b = math.fraction(1,6);
|
||||
assert.equal(typeof compareNatural(a, b), 'number');
|
||||
assert.equal(a.toString(), '0.(3)');
|
||||
assert.equal(b.toString(), '0.1(6)');
|
||||
|
||||
assert.equal(compareNatural(math.fraction(3), math.fraction(2)).valueOf(), 1);
|
||||
assert.equal(compareNatural(math.fraction(2), math.fraction(3)).valueOf(), -1);
|
||||
assert.equal(compareNatural(math.fraction(3), math.fraction(3)).valueOf(), 0);
|
||||
|
||||
assert.strictEqual(compareNatural(math.add(math.fraction(0.1), math.fraction(0.2)), math.fraction(0.3)).valueOf(), 0); // this would fail with numbers
|
||||
});
|
||||
|
||||
it('should compare two measures of the same unit', function() {
|
||||
assert.strictEqual(compareNatural(unit('100cm'), unit('10inch')), 1);
|
||||
assert.strictEqual(compareNatural(unit('99cm'), unit('1m')), -1);
|
||||
assert.strictEqual(compareNatural(unit('1m'), unit('1m')), 0);
|
||||
assert.strictEqual(compareNatural(unit('1m'), unit('100 cm')), 0);
|
||||
assert.strictEqual(compareNatural(unit('101cm'), unit('1m')), 1);
|
||||
});
|
||||
|
||||
it('should compare two measures of different unit', function() {
|
||||
assert.strictEqual(compareNatural(math.unit(5, 'km'), math.unit(100, 'gram')), -1);
|
||||
assert.strictEqual(compareNatural(math.unit(4, 'km/h'), math.unit(2, 'm/s^2')), -1);
|
||||
assert.strictEqual(compareNatural(math.unit(2, 'm/s^2'), math.unit(4, 'km/h')), 1);
|
||||
});
|
||||
|
||||
it('should compare mixed types (by type name)', function() {
|
||||
// booleans
|
||||
assert.strictEqual (compareNatural(2, true), 1);
|
||||
assert.strictEqual (compareNatural(0, false), 1);
|
||||
assert.strictEqual (compareNatural(true, 2), -1);
|
||||
assert.strictEqual (compareNatural(false, 2), -1);
|
||||
|
||||
// null
|
||||
assert.strictEqual (compareNatural(2, null), 1);
|
||||
assert.strictEqual (compareNatural(null, 2), -1);
|
||||
|
||||
// undefined
|
||||
assert.strictEqual (compareNatural(2, undefined), -1);
|
||||
assert.strictEqual (compareNatural(undefined, 2), 1);
|
||||
|
||||
// fractions and units
|
||||
assert.strictEqual (compareNatural(1, math.fraction(1,3)), 1);
|
||||
assert.strictEqual (compareNatural(math.fraction(1,3), 1), -1);
|
||||
|
||||
// units and numbers
|
||||
assert.strictEqual (compareNatural(unit('100cm'), 22), -1);
|
||||
assert.strictEqual (compareNatural(22, unit('100cm')), 1);
|
||||
|
||||
// units and bignumbers
|
||||
assert.strictEqual (compareNatural(unit('100cm'), bignumber(22)), 1);
|
||||
assert.strictEqual (compareNatural(bignumber(22), unit('100cm')), -1);
|
||||
|
||||
// numbers and complex
|
||||
assert.strictEqual (compareNatural(1, complex(2,3)), 1);
|
||||
assert.strictEqual (compareNatural(complex(2,3), 1), -1);
|
||||
|
||||
// numbers and bignumbers
|
||||
assert.strictEqual (compareNatural(bignumber(2), 3), -1);
|
||||
assert.strictEqual (compareNatural(2, bignumber(2)), 1);
|
||||
|
||||
// array, DenseMatrix, SparseMatrix
|
||||
assert.strictEqual (compareNatural(matrix([2]), [2]), 1);
|
||||
assert.strictEqual (compareNatural(sparse([2]), [2]), 1);
|
||||
assert.strictEqual (compareNatural(sparse([2]), matrix([2])), 1);
|
||||
|
||||
// string and number
|
||||
assert.strictEqual (compareNatural('0', 0), 1);
|
||||
});
|
||||
|
||||
it('should perform natural comparison for two strings', function() {
|
||||
assert.strictEqual(compareNatural('abd', 'abc'), 1);
|
||||
assert.strictEqual(compareNatural('abc', 'abc'), 0);
|
||||
assert.strictEqual(compareNatural('abc', 'abd'), -1);
|
||||
|
||||
// natural sorting of strings
|
||||
assert.strictEqual(compareNatural('10', '2'), 1);
|
||||
});
|
||||
|
||||
it('should compare arrays', function () {
|
||||
// different number of dimensions
|
||||
// Note: for arrays we don't compare the number of dimensions!
|
||||
assert.strictEqual(compareNatural([[2]], [1]), -1);
|
||||
|
||||
// different size
|
||||
assert.strictEqual(compareNatural([[2,3]], [[4]]), 1);
|
||||
|
||||
// different content
|
||||
assert.strictEqual(compareNatural([[2,3]], [[2,4]]), -1);
|
||||
|
||||
// equal
|
||||
assert.strictEqual(compareNatural([[2,3], [5,6]], [[2,3], [5,6]]), 0);
|
||||
});
|
||||
|
||||
it('should compare dense matrices', function () {
|
||||
// different number of dimensions
|
||||
assert.strictEqual(compareNatural(matrix([[2]]), matrix([1])), 1);
|
||||
|
||||
// different size
|
||||
assert.strictEqual(compareNatural(matrix([[2,3]]), matrix([[4]])), 1);
|
||||
|
||||
// different content
|
||||
assert.strictEqual(compareNatural(matrix([[2,3]]), matrix([[2,4]])), -1);
|
||||
|
||||
// equal
|
||||
assert.strictEqual(compareNatural(matrix([[2,3], [5,6]]), matrix([[2,3], [5,6]])), 0);
|
||||
});
|
||||
|
||||
it('should compare sparse matrices', function () {
|
||||
// different number of dimensions
|
||||
assert.strictEqual(compareNatural(sparse([[2]]), sparse([1])), 1);
|
||||
|
||||
// different size
|
||||
assert.strictEqual(compareNatural(sparse([[2,3]]), sparse([[4]])), 1);
|
||||
|
||||
// different content
|
||||
assert.strictEqual(compareNatural(sparse([[2,3]]), sparse([[2,4]])), -1);
|
||||
|
||||
// equal
|
||||
assert.strictEqual(compareNatural(sparse([[2,3], [5,6]]), sparse([[2,3], [5,6]])), 0);
|
||||
});
|
||||
|
||||
it('should compare objects', function () {
|
||||
// different number of keys
|
||||
assert.strictEqual(compareNatural({a:2, b:3}, {a:2}), 1);
|
||||
|
||||
// different keys
|
||||
assert.strictEqual(compareNatural({b:3}, {a:2}), 1);
|
||||
|
||||
// different values
|
||||
assert.strictEqual(compareNatural({a:3}, {a:2}), 1);
|
||||
|
||||
// equal
|
||||
assert.strictEqual(compareNatural({a:2, b:3}, {a:2, b:3}), 0);
|
||||
|
||||
// nesting
|
||||
assert.strictEqual(compareNatural({a:2, b: {c: 4}}, {a:2, b: {c: 3}}), 1);
|
||||
assert.strictEqual(compareNatural({a:2, b: {c: 3}}, {a:2, b: {c: 4}}), -1);
|
||||
});
|
||||
|
||||
it('should apply configuration option epsilon', function() {
|
||||
var mymath = math.create();
|
||||
|
||||
assert.equal(mymath.compareNatural(1, 0.991), 1);
|
||||
assert.equal(mymath.compareNatural(math.bignumber(1), math.bignumber(0.991)).valueOf(), 1);
|
||||
|
||||
mymath.config({epsilon: 1e-2});
|
||||
assert.equal(mymath.compareNatural(1, 0.991), 0);
|
||||
assert.equal(mymath.compareNatural(math.bignumber(1), math.bignumber(0.991)), 0);
|
||||
});
|
||||
|
||||
it('should compare complex numbers', function() {
|
||||
assert.equal(compareNatural(complex(1,1), complex(1,1)), 0);
|
||||
assert.equal(compareNatural(complex(2,1), complex(1,2)), 1);
|
||||
assert.equal(compareNatural(complex(0,1), complex(1,2)), -1);
|
||||
});
|
||||
|
||||
it('should throw an error in case of invalid number of arguments', function() {
|
||||
assert.throws(function () {compareNatural(1);}, /TypeError: Too few arguments/);
|
||||
assert.throws(function () {compareNatural(1, 2, 3);}, /TypeError: Too many arguments/);
|
||||
});
|
||||
|
||||
it('should LaTeX compare', function () {
|
||||
var expression = math.parse('compareNatural(1,2)');
|
||||
assert.equal(expression.toTex(), '\\mathrm{compareNatural}\\left(1,2\\right)');
|
||||
});
|
||||
});
|
||||
@ -1,220 +0,0 @@
|
||||
// test deepStrictCompare
|
||||
var assert = require('assert'),
|
||||
math = require('../../../index'),
|
||||
bignumber = math.bignumber,
|
||||
complex = math.complex,
|
||||
matrix = math.matrix,
|
||||
sparse = math.sparse,
|
||||
unit = math.unit,
|
||||
deepStrictCompare = math.deepStrictCompare;
|
||||
|
||||
describe('deepStrictCompare', function() {
|
||||
|
||||
it('should compare two numbers correctly', function() {
|
||||
assert.equal(deepStrictCompare(2, 3), -1);
|
||||
assert.equal(deepStrictCompare(2, 2), 0);
|
||||
assert.equal(deepStrictCompare(2, 1), 1);
|
||||
assert.equal(deepStrictCompare(0, 0), 0);
|
||||
assert.equal(deepStrictCompare(-2, 2), -1);
|
||||
assert.equal(deepStrictCompare(-2, -3), 1);
|
||||
assert.equal(deepStrictCompare(-3, -2), -1);
|
||||
});
|
||||
|
||||
it('should compare two floating point numbers correctly', function() {
|
||||
// Infinity
|
||||
assert.equal(deepStrictCompare(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY), 0);
|
||||
assert.equal(deepStrictCompare(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY), 0);
|
||||
assert.equal(deepStrictCompare(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY), 1);
|
||||
assert.equal(deepStrictCompare(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY), -1);
|
||||
assert.equal(deepStrictCompare(Number.POSITIVE_INFINITY, 2.0), 1);
|
||||
assert.equal(deepStrictCompare(2.0, Number.POSITIVE_INFINITY), -1);
|
||||
assert.equal(deepStrictCompare(Number.NEGATIVE_INFINITY, 2.0), -1);
|
||||
assert.equal(deepStrictCompare(2.0, Number.NEGATIVE_INFINITY), 1);
|
||||
// floating point numbers
|
||||
assert.equal(deepStrictCompare(0.3 - 0.2, 0.1), 0);
|
||||
});
|
||||
|
||||
it('should compare two booleans', function() {
|
||||
assert.equal(deepStrictCompare(true, true), 0);
|
||||
assert.equal(deepStrictCompare(true, false), 1);
|
||||
assert.equal(deepStrictCompare(false, true), -1);
|
||||
assert.equal(deepStrictCompare(false, false), 0);
|
||||
});
|
||||
|
||||
it('should compare bignumbers', function() {
|
||||
assert.strictEqual(deepStrictCompare(bignumber(2), bignumber(3)), -1);
|
||||
assert.strictEqual(deepStrictCompare(bignumber(2), bignumber(2)), 0);
|
||||
assert.strictEqual(deepStrictCompare(bignumber(3), bignumber(2)), 1);
|
||||
assert.strictEqual(deepStrictCompare(bignumber(0), bignumber(0)), 0);
|
||||
assert.strictEqual(deepStrictCompare(bignumber(-2), bignumber(2)), -1);
|
||||
});
|
||||
|
||||
it('should compare two fractions', function() {
|
||||
var a = math.fraction(1,3);
|
||||
var b = math.fraction(1,6);
|
||||
assert(deepStrictCompare(a, b) instanceof math.type.Fraction);
|
||||
assert.equal(a.toString(), '0.(3)');
|
||||
assert.equal(b.toString(), '0.1(6)');
|
||||
|
||||
assert.equal(deepStrictCompare(math.fraction(3), math.fraction(2)).valueOf(), 1);
|
||||
assert.equal(deepStrictCompare(math.fraction(2), math.fraction(3)).valueOf(), -1);
|
||||
assert.equal(deepStrictCompare(math.fraction(3), math.fraction(3)).valueOf(), 0);
|
||||
|
||||
assert.strictEqual(deepStrictCompare(math.add(math.fraction(0.1), math.fraction(0.2)), math.fraction(0.3)).valueOf(), 0); // this would fail with numbers
|
||||
});
|
||||
|
||||
it('should compare two measures of the same unit', function() {
|
||||
assert.equal(deepStrictCompare(unit('100cm'), unit('10inch')), 1);
|
||||
assert.equal(deepStrictCompare(unit('99cm'), unit('1m')), -1);
|
||||
assert.equal(deepStrictCompare(unit('1m'), unit('1m')), bignumber(0));
|
||||
assert.equal(deepStrictCompare(unit('101cm'), unit('1m')), 1);
|
||||
});
|
||||
|
||||
it('should throw an error for two measures of different units', function() {
|
||||
|
||||
// TODO: compare units with different base
|
||||
|
||||
assert.throws(function () {deepStrictCompare(math.unit(5, 'km'), math.unit(100, 'gram'));});
|
||||
});
|
||||
|
||||
it('should compare mixed types (by type name)', function() {
|
||||
// booleans
|
||||
assert.strictEqual (deepStrictCompare(2, true), 1);
|
||||
assert.strictEqual (deepStrictCompare(0, false), 1);
|
||||
assert.strictEqual (deepStrictCompare(true, 2), -1);
|
||||
assert.strictEqual (deepStrictCompare(false, 2), -1);
|
||||
|
||||
// null
|
||||
assert.strictEqual (deepStrictCompare(2, null), 1);
|
||||
assert.strictEqual (deepStrictCompare(null, 2), -1);
|
||||
|
||||
// undefined
|
||||
assert.strictEqual (deepStrictCompare(2, undefined), -1);
|
||||
assert.strictEqual (deepStrictCompare(undefined, 2), 1);
|
||||
|
||||
// fractions and units
|
||||
assert.strictEqual (deepStrictCompare(1, math.fraction(1,3)), 1);
|
||||
assert.strictEqual (deepStrictCompare(math.fraction(1,3), 1), -1);
|
||||
|
||||
// units and numbers
|
||||
assert.strictEqual (deepStrictCompare(unit('100cm'), 22), -1);
|
||||
assert.strictEqual (deepStrictCompare(22, unit('100cm')), 1);
|
||||
|
||||
// units and bignumbers
|
||||
assert.strictEqual (deepStrictCompare(unit('100cm'), bignumber(22)), 1);
|
||||
assert.strictEqual (deepStrictCompare(bignumber(22), unit('100cm')), -1);
|
||||
|
||||
// numbers and complex
|
||||
assert.strictEqual (deepStrictCompare(1, complex(2,3)), 1);
|
||||
assert.strictEqual (deepStrictCompare(complex(2,3), 1), -1);
|
||||
|
||||
// numbers and bignumbers
|
||||
assert.strictEqual (deepStrictCompare(bignumber(2), 3), -1);
|
||||
assert.strictEqual (deepStrictCompare(2, bignumber(2)), 1);
|
||||
|
||||
// array, DenseMatrix, SparseMatrix
|
||||
assert.strictEqual (deepStrictCompare(matrix([2]), [2]), 1);
|
||||
assert.strictEqual (deepStrictCompare(sparse([2]), [2]), 1);
|
||||
assert.strictEqual (deepStrictCompare(sparse([2]), matrix([2])), 1);
|
||||
|
||||
// string and number
|
||||
assert.strictEqual (deepStrictCompare('0', 0), 1);
|
||||
});
|
||||
|
||||
it('should perform natural comparison for two strings', function() {
|
||||
assert.equal(deepStrictCompare('abd', 'abc'), 1);
|
||||
assert.equal(deepStrictCompare('abc', 'abc'), 0);
|
||||
assert.equal(deepStrictCompare('abc', 'abd'), -1);
|
||||
|
||||
// no natural sorting here
|
||||
assert.equal(deepStrictCompare('10', '2'), -1);
|
||||
});
|
||||
|
||||
it('should compare arrays', function () {
|
||||
// different number of dimensions
|
||||
// Note: for arrays we don't compare the number of dimensions!
|
||||
assert.strictEqual(deepStrictCompare([[2]], [1]), -1);
|
||||
|
||||
// different size
|
||||
assert.strictEqual(deepStrictCompare([[2,3]], [[4]]), 1);
|
||||
|
||||
// different content
|
||||
assert.strictEqual(deepStrictCompare([[2,3]], [[2,4]]), -1);
|
||||
|
||||
// equal
|
||||
assert.strictEqual(deepStrictCompare([[2,3], [5,6]], [[2,3], [5,6]]), 0);
|
||||
});
|
||||
|
||||
it('should compare dense matrices', function () {
|
||||
// different number of dimensions
|
||||
assert.strictEqual(deepStrictCompare(matrix([[2]]), matrix([1])), 1);
|
||||
|
||||
// different size
|
||||
assert.strictEqual(deepStrictCompare(matrix([[2,3]]), matrix([[4]])), 1);
|
||||
|
||||
// different content
|
||||
assert.strictEqual(deepStrictCompare(matrix([[2,3]]), matrix([[2,4]])), -1);
|
||||
|
||||
// equal
|
||||
assert.strictEqual(deepStrictCompare(matrix([[2,3], [5,6]]), matrix([[2,3], [5,6]])), 0);
|
||||
});
|
||||
|
||||
it('should compare sparse matrices', function () {
|
||||
// different number of dimensions
|
||||
assert.strictEqual(deepStrictCompare(sparse([[2]]), sparse([1])), 1);
|
||||
|
||||
// different size
|
||||
assert.strictEqual(deepStrictCompare(sparse([[2,3]]), sparse([[4]])), 1);
|
||||
|
||||
// different content
|
||||
assert.strictEqual(deepStrictCompare(sparse([[2,3]]), sparse([[2,4]])), -1);
|
||||
|
||||
// equal
|
||||
assert.strictEqual(deepStrictCompare(sparse([[2,3], [5,6]]), sparse([[2,3], [5,6]])), 0);
|
||||
});
|
||||
|
||||
it('should compare objects', function () {
|
||||
// different number of keys
|
||||
assert.strictEqual(deepStrictCompare({a:2, b:3}, {a:2}), 1);
|
||||
|
||||
// different keys
|
||||
assert.strictEqual(deepStrictCompare({b:3}, {a:2}), 1);
|
||||
|
||||
// different values
|
||||
assert.strictEqual(deepStrictCompare({a:3}, {a:2}), 1);
|
||||
|
||||
// equal
|
||||
assert.strictEqual(deepStrictCompare({a:2, b:3}, {a:2, b:3}), 0);
|
||||
|
||||
// nesting
|
||||
assert.strictEqual(deepStrictCompare({a:2, b: {c: 4}}, {a:2, b: {c: 3}}), 1);
|
||||
assert.strictEqual(deepStrictCompare({a:2, b: {c: 3}}, {a:2, b: {c: 4}}), -1);
|
||||
});
|
||||
|
||||
it('should apply configuration option epsilon', function() {
|
||||
var mymath = math.create();
|
||||
|
||||
assert.equal(mymath.deepStrictCompare(1, 0.991), 1);
|
||||
assert.equal(mymath.deepStrictCompare(math.bignumber(1), math.bignumber(0.991)).valueOf(), 1);
|
||||
|
||||
mymath.config({epsilon: 1e-2});
|
||||
assert.equal(mymath.deepStrictCompare(1, 0.991), 0);
|
||||
assert.equal(mymath.deepStrictCompare(math.bignumber(1), math.bignumber(0.991)), 0);
|
||||
});
|
||||
|
||||
it('should compare complex numbers', function() {
|
||||
assert.equal(deepStrictCompare(complex(1,1), complex(1,1)), 0);
|
||||
assert.equal(deepStrictCompare(complex(2,1), complex(1,2)), 1);
|
||||
assert.equal(deepStrictCompare(complex(0,1), complex(1,2)), -1);
|
||||
});
|
||||
|
||||
it('should throw an error in case of invalid number of arguments', function() {
|
||||
assert.throws(function () {deepStrictCompare(1);}, /TypeError: Too few arguments/);
|
||||
assert.throws(function () {deepStrictCompare(1, 2, 3);}, /TypeError: Too many arguments/);
|
||||
});
|
||||
|
||||
it('should LaTeX compare', function () {
|
||||
var expression = math.parse('deepStrictCompare(1,2)');
|
||||
assert.equal(expression.toTex(), '\\mathrm{deepStrictCompare}\\left(1,2\\right)');
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user