added sort to most types that have ordered elements...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2020-10-07 16:46:59 +03:00
parent 5816bf779d
commit 891f332fa2
8 changed files with 196 additions and 78 deletions

107
Array.js
View File

@ -94,53 +94,6 @@ Array.prototype.compact = function(){
})
// Convert an array to object...
//
// Format:
// {
// <item>: <index>,
// ...
// }
//
// 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([
// [<item>, <index>],
// ...
// ])
//
// 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:
// {
// <item>: <index>,
// ...
// }
//
// 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([
// [<item>, <index>],
// ...
// ])
//
// 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()) }
/**********************************************************************

37
Map.js Normal file
View File

@ -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 })

View File

@ -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) }
/**********************************************************************

View File

@ -12,12 +12,11 @@ A library of JavaScript type extensions, types and type utilities.
- [`Object.matchPartial(..)`](#objectmatchpartial)
- [`Object.flatCopy(..)`](#objectflatcopy)
- [`<object>.run(..)`](#objectrun)
- [`Object.sort(..)`](#objectsort)
- [`Array`](#array)
- [`<array>.first(..)` / `<array>.last(..)`](#arrayfirst--arraylast)
- [`<array>.compact()`](#arraycompact)
- [`<array>.len`](#arraylen)
- [`<array>.toKeys(..)`](#arraytokeys)
- [`<array>.toMap(..)`](#arraytomap)
- [`<array>.unique(..)` / `<array>.tailUnique(..)`](#arrayunique--arraytailunique)
- [`<array>.cmp(..)`](#arraycmp)
- [`<array>.setCmp(..)`](#arraysetcmp)
@ -26,13 +25,18 @@ A library of JavaScript type extensions, types and type utilities.
- [`<array>.mapChunks(..)`](#arraymapchunks)
- [`<array>.filterChunks(..)`](#arrayfilterchunks)
- [`<array>.reduceChunks(..)`](#arrayreducechunks)
- [`<array>.toKeys(..)`](#arraytokeys)
- [`<array>.toMap(..)`](#arraytomap)
- [`Array` (polyfill)](#array-polyfill)
- [`<array>.flat()`](#arrayflat)
- [`<array>.includes()`](#arrayincludes)
- [`Map`](#map)
- [`<map>.sort(..)`](#mapsort)
- [`Set`](#set)
- [`<set>.unite(..)`](#setunite)
- [`<set>.intersect(..)`](#setintersect)
- [`<set>.subtract(..)`](#setsubtract)
- [`<set>.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`
#### `<array>.first(..)` / `<array>.last(..)`
Get or set the first/last items of `<array>`.
Get the first/last items of `<array>`.
```
<array>.first()
-> <item>
<array>.last()
-> <item>
```
Set the first/last items of `<array>`.
```
<array>.first(<item>)
-> <array>
<array>.last(<item>)
-> <array>
```
Note that these do not affect `<array>` length unless setting items on
an empty `<array>`.
#### `<array>.compact()`
```
<array>.compact()
-> <compact-array>
```
Generate a compact `<array>` from a sparse `<array>`, i.e. removing all
the empty slots.
@ -161,10 +193,16 @@ the empty slots.
Number of non-empty slots/elements in `<array>`.
This is similar to:
```javascript
var L = [,,, 1,, 2, 3,,]
#### `<array>.toKeys(..)`
// this is the same as L.len...
L.compact().length
```
#### `<array>.toMap(..)`
Note that this is different from `.length` in that writing to `.len` has
no effect.
#### `<array>.unique(..)` / `<array>.tailUnique(..)`
@ -172,6 +210,19 @@ Generate an array with all duplicate elements removed.
#### `<array>.cmp(..)`
```
<array>.cmp(<other>)
-> <bool>
```
Compare `<array>` to `<other>`.
This will return `true` if:
- `<array>` === `<other>` or,
- lengths are the same and,
- values on the same positions are equal.
#### `<array>.setCmp(..)`
#### `<array>.sortAs(..)`
@ -184,6 +235,10 @@ Generate an array with all duplicate elements removed.
#### `<array>.reduceChunks(..)`
#### `<array>.toKeys(..)`
#### `<array>.toMap(..)`
### `Array` (polyfill)
@ -192,6 +247,11 @@ Generate an array with all duplicate elements removed.
#### `<array>.includes()`
### `Map`
#### `<map>.sort(..)`
### `Set`
#### `<set>.unite(..)`
@ -200,6 +260,8 @@ Generate an array with all duplicate elements removed.
#### `<set>.subtract(..)`
#### `<set>.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

15
Set.js
View File

@ -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 }
/**********************************************************************

View File

@ -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 },

View File

@ -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": {

View File

@ -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