diff --git a/Array.js b/Array.js index fdbedb7..321ddb2 100644 --- a/Array.js +++ b/Array.js @@ -94,53 +94,6 @@ Array.prototype.compact = function(){ }) -// Convert an array to object... -// -// Format: -// { -// : , -// ... -// } -// -// NOTE: items should be strings, other types will get converted to -// strings and thus may mess things up. -// NOTE: this will forget repeating items... -// NOTE: normalize will slow things down... -Array.prototype.toKeys = function(normalize){ - return normalize ? - this.reduce(function(r, e, i){ - r[normalize(e)] = i - return r }, {}) - : this.reduce(function(r, e, i){ - r[e] = i - return r }, {}) } - - -// Convert an array to a map... -// -// This is similar to Array.prototype.toKeys(..) but does not restrict -// value type to string. -// -// Format: -// Map([ -// [, ], -// ... -// ]) -// -// NOTE: this will forget repeating items... -// NOTE: normalize will slow things down... -Array.prototype.toMap = function(normalize){ - return normalize ? - this - .reduce(function(m, e, i){ - m.set(normalize(e), i) - return m }, new Map()) - : this - .reduce(function(m, e, i){ - m.set(e, i) - return m }, new Map()) } - - // Return an array with duplicate elements removed... // // NOTE: order is preserved... @@ -155,8 +108,10 @@ Array.prototype.tailUnique = function(normalize){ .unique(normalize) .reverse() } + // Compare two arrays... // +// XXX unify this with ./Object.js (.match(..)) and diff.js Array.prototype.cmp = function(other){ if(this === other){ return true } @@ -170,17 +125,10 @@ Array.prototype.cmp = function(other){ // Compare two Arrays as sets... // -// This will ignore order -// -// XXX should we use Set(..) here??? +// NOTE: this will ignore order and repeating elments... Array.prototype.setCmp = function(other){ return this === other - || this - .unique() - .sort() - .cmp(other - .unique() - .sort()) } + || (new Set([...this, ...other])).length == (new Set(this)).length } // Sort as the other array... @@ -321,6 +269,53 @@ Array.prototype.reduceChunks = makeChunkIter('reduce', e[1], e[0], array) }) +// Convert an array to object... +// +// Format: +// { +// : , +// ... +// } +// +// NOTE: items should be strings, other types will get converted to +// strings and thus may mess things up. +// NOTE: this will forget repeating items... +// NOTE: normalize will slow things down... +Array.prototype.toKeys = function(normalize){ + return normalize ? + this.reduce(function(r, e, i){ + r[normalize(e)] = i + return r }, {}) + : this.reduce(function(r, e, i){ + r[e] = i + return r }, {}) } + + +// Convert an array to a map... +// +// This is similar to Array.prototype.toKeys(..) but does not restrict +// value type to string. +// +// Format: +// Map([ +// [, ], +// ... +// ]) +// +// NOTE: this will forget repeating items... +// NOTE: normalize will slow things down... +Array.prototype.toMap = function(normalize){ + return normalize ? + this + .reduce(function(m, e, i){ + m.set(normalize(e), i) + return m }, new Map()) + : this + .reduce(function(m, e, i){ + m.set(e, i) + return m }, new Map()) } + + /********************************************************************** diff --git a/Map.js b/Map.js new file mode 100644 index 0000000..42d6033 --- /dev/null +++ b/Map.js @@ -0,0 +1,37 @@ +/********************************************************************** +* +* +* +**********************************************/ /* c8 ignore next 2 */ +((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define) +(function(require){ var module={} // make module AMD/node compatible... +/*********************************************************************/ + + + + +/*********************************************************************/ + +// NOTE: we do not touch .__keys here as no renaming is ever done... +// XXX this essentially rewrites the whole map, is there a faster/better +// way to do this??? +Map.prototype.sort = function(keys){ + keys = (typeof(keys) == 'function' + || keys === undefined) ? + [...this.keys()].sort(keys) + : keys + var del = Map.prototype.delete.bind(this) + var set = Map.prototype.set.bind(this) + new Set([...keys, ...this.keys()]) + .forEach(function(k){ + if(this.has(k)){ + var v = this.get(k) + del(k) + set(k, v) } }.bind(this)) + return this } + + + + +/********************************************************************** +* vim:set ts=4 sw=4 : */ return module }) diff --git a/Object.js b/Object.js index b400f3f..f9fcbc7 100644 --- a/Object.js +++ b/Object.js @@ -20,6 +20,7 @@ Object.deepKeys = || object.deepKeys +// XXX unify this with ./Array.js (.match(..)) and diff.js Object.match = Object.match || object.match @@ -38,6 +39,22 @@ Object.flatCopy = function(obj){ return res }, {}) } +Object.sort = function(obj, keys){ + keys = (typeof(keys) == 'function' + || keys === undefined) ? + [...Object.keys(obj)].sort(keys) + : keys + new Set([...keys, ...Object.keys(obj)]) + .forEach(function(k){ + if(k in obj){ + var v = obj[k] + delete obj[k] + obj[k] = v } }) + return obj } +// keep the null prototype clean... +//Object.prototype.sort = function(keys){ +// return Object.sort(this, keys) } + /********************************************************************** diff --git a/README.md b/README.md index b5fad11..5b8710b 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,11 @@ A library of JavaScript type extensions, types and type utilities. - [`Object.matchPartial(..)`](#objectmatchpartial) - [`Object.flatCopy(..)`](#objectflatcopy) - [`.run(..)`](#objectrun) + - [`Object.sort(..)`](#objectsort) - [`Array`](#array) - [`.first(..)` / `.last(..)`](#arrayfirst--arraylast) - [`.compact()`](#arraycompact) - [`.len`](#arraylen) - - [`.toKeys(..)`](#arraytokeys) - - [`.toMap(..)`](#arraytomap) - [`.unique(..)` / `.tailUnique(..)`](#arrayunique--arraytailunique) - [`.cmp(..)`](#arraycmp) - [`.setCmp(..)`](#arraysetcmp) @@ -26,13 +25,18 @@ A library of JavaScript type extensions, types and type utilities. - [`.mapChunks(..)`](#arraymapchunks) - [`.filterChunks(..)`](#arrayfilterchunks) - [`.reduceChunks(..)`](#arrayreducechunks) + - [`.toKeys(..)`](#arraytokeys) + - [`.toMap(..)`](#arraytomap) - [`Array` (polyfill)](#array-polyfill) - [`.flat()`](#arrayflat) - [`.includes()`](#arrayincludes) + - [`Map`](#map) + - [`.sort(..)`](#mapsort) - [`Set`](#set) - [`.unite(..)`](#setunite) - [`.intersect(..)`](#setintersect) - [`.subtract(..)`](#setsubtract) + - [`.sort(..)`](#setsort) - [`Date`](#date) - [`Date.timeStamp(..)`](#datetimestamp) - [`Date.fromTimeStamp(..)`](#datefromtimestamp) @@ -144,15 +148,43 @@ For more info see: https://github.com/flynx/object-run.js +#### `Object.sort(..)` + + + ### `Array` #### `.first(..)` / `.last(..)` -Get or set the first/last items of ``. +Get the first/last items of ``. +``` +.first() + -> + +.last() + -> +``` + +Set the first/last items of ``. +``` +.first() + -> + +.last() + -> +``` + +Note that these do not affect `` length unless setting items on +an empty ``. #### `.compact()` +``` +.compact() + -> +``` + Generate a compact `` from a sparse ``, i.e. removing all the empty slots. @@ -161,10 +193,16 @@ the empty slots. Number of non-empty slots/elements in ``. +This is similar to: +```javascript +var L = [,,, 1,, 2, 3,,] -#### `.toKeys(..)` +// this is the same as L.len... +L.compact().length +``` -#### `.toMap(..)` +Note that this is different from `.length` in that writing to `.len` has +no effect. #### `.unique(..)` / `.tailUnique(..)` @@ -172,6 +210,19 @@ Generate an array with all duplicate elements removed. #### `.cmp(..)` +``` +.cmp() + -> +``` + +Compare `` to ``. + +This will return `true` if: +- `` === `` or, +- lengths are the same and, +- values on the same positions are equal. + + #### `.setCmp(..)` #### `.sortAs(..)` @@ -184,6 +235,10 @@ Generate an array with all duplicate elements removed. #### `.reduceChunks(..)` +#### `.toKeys(..)` + +#### `.toMap(..)` + ### `Array` (polyfill) @@ -192,6 +247,11 @@ Generate an array with all duplicate elements removed. #### `.includes()` +### `Map` + +#### `.sort(..)` + + ### `Set` #### `.unite(..)` @@ -200,6 +260,8 @@ Generate an array with all duplicate elements removed. #### `.subtract(..)` +#### `.sort(..)` + ### `Date` @@ -236,6 +298,9 @@ or, to only import containers: var containers = require('ig-types/containers') ``` +Note that this will also import `Map`. + + ### `containers.UniqueKeyMap()` (`Map`) `UniqueKeyMap` implements a key-value container (i.e. `Map`) that supports diff --git a/Set.js b/Set.js index 29b18e8..dd8d6ad 100644 --- a/Set.js +++ b/Set.js @@ -25,6 +25,21 @@ Set.prototype.subtract = function(other){ .filter(function(e){ return !other.has(e) })) } +Map.prototype.sort = function(keys){ + keys = (typeof(keys) == 'function' + || keys === undefined) ? + [...this].sort(keys) + : keys + var del = Set.prototype.delete.bind(this) + var add = Set.prototype.add.bind(this) + new Set([...keys, ...this]) + .forEach(function(e){ + if(this.has(e)){ + del(e) + add(e) } }.bind(this)) + return this } + + /********************************************************************** diff --git a/containers.js b/containers.js index 48fc817..9a23d3f 100644 --- a/containers.js +++ b/containers.js @@ -7,6 +7,8 @@ (function(require){ var module={} // make module AMD/node compatible... /*********************************************************************/ +require('./Map') + var object = require('ig-object') @@ -84,19 +86,6 @@ module.UniqueKeyMap = object.Constructor('UniqueKeyMap', Map, { return res }, []) } // get keys used to set the values... return [...(this.__keys.get(elem) || [])] }, - // NOTE: we do not touch .__keys here as no renaming is ever done... - // XXX this essentially rewrites the whole map, is there a faster/better - // way to do this??? - sortKeysAs: function(keys){ - var del = object.parent(UniqueKeyMap.prototype, 'delete').bind(this) - var set = object.parent(UniqueKeyMap.prototype, 'set').bind(this) - new Set([...keys, ...this.keys()]) - .forEach(function(k){ - var v = this.get(k) - del(k) - set(k, v) }.bind(this)) - return this }, - // NOTE: this will never overwrite a key's value, to overwrite use .reset(..) set: function(key, elem, return_key=false){ @@ -167,7 +156,7 @@ module.UniqueKeyMap = object.Constructor('UniqueKeyMap', Map, { var n = this.set(to, e, true) // keep order... keys.splice(keys.indexOf(from), 1, n) - this.sortKeysAs(keys) + this.sort(keys) return return_key ? n : this }, diff --git a/package.json b/package.json index cc8365d..4bbcdeb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ig-types", - "version": "2.0.12", + "version": "2.0.14", "description": "Generic JavaScript types and type extensions...", "main": "main.js", "scripts": { diff --git a/test.js b/test.js index 8999c43..2437496 100755 --- a/test.js +++ b/test.js @@ -43,9 +43,9 @@ var cases = test.Cases({ y: 333, z: 444, }) - var oo = Object.flatCopy(o) + var oo = assert(Object.flatCopy(o), 'Object.flatCopy(..)') - assert(Object.match(oo, {x: 111, y: 333, z: 444}), '') + assert(Object.match(oo, {x: 111, y: 333, z: 444}), 'Object.match(..)') }, // Array.js