UNPKG

@jmparsons/ccxt

Version:

A JavaScript / Python / PHP cryptocurrency trading library with support for 100+ exchanges

228 lines (160 loc) 5.83 kB
"use strict"; /* ------------------------------------------------------------------------ */ const { isObject, isNumber, isDictionary, isArray } = require ('./type') /* ------------------------------------------------------------------------ */ const keys = Object.keys , values = x => !isArray (x) // don't copy arrays if they're already arrays! ? Object.values (x) : x , index = x => new Set (values (x)) , extend = (...args) => Object.assign ({}, ...args) // NB: side-effect free , clone = x => isArray (x) ? Array.from (x) // clones arrays : extend (x) // clones objects /* ------------------------------------------------------------------------ */ module.exports = { keys , values , extend , clone , index , ordered: x => x // a stub to keep assoc keys in order (in JS it does nothing, it's mostly for Python) , unique: x => Array.from (index (x)) /* ............................................. */ , inArray (needle, haystack) { return haystack.includes (needle) } , toArray (object) { return Object.values (object) } /* ............................................. */ , keysort (x, out = {}) { for (const k of keys (x).sort ()) out[k] = x[k] return out } /* ............................................. */ /* Accepts a map/array of objects and a key name to be used as an index: array = [ { someKey: 'value1', anotherKey: 'anotherValue1' }, { someKey: 'value2', anotherKey: 'anotherValue2' }, { someKey: 'value3', anotherKey: 'anotherValue3' }, ] key = 'someKey' Returns a map: { value1: { someKey: 'value1', anotherKey: 'anotherValue1' }, value2: { someKey: 'value2', anotherKey: 'anotherValue2' }, value3: { someKey: 'value3', anotherKey: 'anotherValue3' }, } */ , indexBy (x, k, out = {}) { for (const v of values (x)) if (k in v) out[v[k]] = v return out } /* ............................................. */ /* Accepts a map/array of objects and a key name to be used as a grouping parameter: array = [ { someKey: 'value1', anotherKey: 'anotherValue1' }, { someKey: 'value1', anotherKey: 'anotherValue2' }, { someKey: 'value3', anotherKey: 'anotherValue3' }, ] key = 'someKey' Returns a map: { value1: [ { someKey: 'value1', anotherKey: 'anotherValue1' }, { someKey: 'value1', anotherKey: 'anotherValue2' }, ] value3: [ { someKey: 'value3', anotherKey: 'anotherValue3' } ], } */ , groupBy (x, k, out = {}) { for (const v of values (x)) { if (k in v) { const p = v[k] out[p] = out[p] || [] out[p].push (v) } } return out } /* ............................................. */ /* Accepts a map/array of objects, a key name and a key value to be used as a filter: array = [ { someKey: 'value1', anotherKey: 'anotherValue1' }, { someKey: 'value2', anotherKey: 'anotherValue2' }, { someKey: 'value3', anotherKey: 'anotherValue3' }, ] key = 'someKey' value = 'value1' Returns an array: [ value1: { someKey: 'value1', anotherKey: 'anotherValue1' }, ] */ , filterBy (x, k, value = undefined, out = []) { for (const v of values (x)) if (v[k] === value) out.push (v) return out } /* ............................................. */ , sortBy: (array, // NB: MUTATES ARRAY! key, descending = false, direction = descending ? -1 : 1) => array.sort ((a, b) => ((a[key] < b[key]) ? -direction : ((a[key] > b[key]) ? direction : 0))) /* ............................................. */ , flatten: function flatten (x, out = []) { for (const v of x) { if (isArray (v)) flatten (v, out) else out.push (v) } return out } /* ............................................. */ , pluck: (x, k) => values (x) .filter (v => k in v) .map (v => v[k]) /* ............................................. */ , omit (x, ...args) { const out = clone (x) for (const k of args) { if (isArray (k)) // omit (x, ['a', 'b']) for (const kk of k) delete out[kk] else delete out[k] // omit (x, 'a', 'b') } return out } /* ............................................. */ , sum (...xs) { const ns = xs.filter (isNumber) // leave only numbers return (ns.length > 0) ? ns.reduce ((a, b) => a + b, 0) : undefined } /* ............................................. */ , deepExtend: function deepExtend (...xs) { let out = undefined for (const x of xs) { if (isDictionary (x)) { if (!isObject (out)) out = {} for (const k in x) out[k] = deepExtend (out[k], x[k]) } else out = x } return out } /* ------------------------------------------------------------------------ */ }