This package has been deprecated

Author message:

Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.

pycollections

0.9.1 • Public • Published

pycollections.js

collections.py for JavaScript

pycollections.js contains class definitions for Dict, DefaultDict, Counter, OrderedDict, and NamedTuple, stocked with functionality that (mostly) mirrors their collections.py counterparts and exceeds that of the ES6 Map class.

It has been tested on NodeJS v20.8.1, and the latest Chrome, Firefox, and Safari browsers.


Contents


Getting it

NPM

npm install pycollections

Bower

bower install pycollections

cdnjs

Coming soon!



Dict

Static methods:

  • fromKeys(keys, opt_valueForAllKeys)

Instance methods:

  • clear()
  • copy()
  • set(key, value)
  • update(iterable)
  • hasKey(key)
  • get(key, opt_defaultValue)
  • del(key)
  • pop(key, opt_defaultValue)
  • iterkeys(cb)
  • keys()
  • popitem()
  • length()
  • iteritems(cb)
  • items()
  • itervalues(cb)
  • values()

Instance methods (not present in Python dict):

  • getFirstKey()
  • getFirstMatchingKey(predicate)
  • isEmpty()
  • setOneNewValue(key, fn)
  • setSomeNewValues(keys, fn)
  • setAllNewValues(fn)

Demo

Creating a new Dict

py = {}
py = dict.fromkeys([1, 2, 3], {'the': 'value'})
py = dict(a=1, b=2)
py = dict([('a', 1), ('b', 2)])
py = dict(dict(a=1))
py = dict(123)  # raises TypeError
var js = new Dict();
var js = Dict.fromKeys([1, 2, 3], {'the': 'value'});
var js = new Dict({'a': 1, 'b': 2});
var js = new Dict([['a', 1], ['b', 2]]);
var js = new Dict(new Dict({'a': 1}));
var js = new Dict(123);  // throws Error

Detecting presence of a key

py = {}
987 in py  # False
[] in py  # raises TypeError due to unhashable key
var js = new Dict();
js.hasKey(987);  // false
js.hasKey([]);  // throws DictKeyNotHashable

Getting a potentially-missing key's value

py = {}
py['missing key']  # raises KeyError
py.get('missing key', 'default')  # 'default'
py.get('missing key')  # None
py[[]]  # raises TypeError due to unhashable key
py.get([])  # raises TypeError due to unhashable key
var js = new Dict();
js.get('my key');  // throws DictKeyNotFound
js.get('missing key', 'default');  // 'default'
// Must explicitly pass null/undefined as the default;
// when passing only one .get() argument, the key is must exist,
// otherwise it thows an error.
js.get('missing key', null);  // null
js.get([]);  // throws DictKeyNotHashable
js.get([], null);  // throws DictKeyNotHashable

Distinguishing between keys of different types

Support for distinct Boolean, Number, String, NaN, null, and undefined keys.

py = {}
py[8] = 'num'
8 in py  # True
'8' in py  # False
len(py)  # 1

py['8'] = 'str'
len(py)  # 2
py[8]  # 'num'
py['8']  # 'str'
var js = new Dict();
js.set(8, 'num');
js.hasKey(8); // true
js.hasKey('8'); // false
js.length(); // 1

js.set('8', 'str');
js.length();  // 2
js.get(8);  // 'num'
js.get('8');  // 'str'

Deleting a key

py = {'a': 1}
del py['a']
del py['b']  # raises KeyError
var js = new Dict({'a': 1});
js.del('a');
js.del('b');  // throws DictKeyNotFound

Popping a key

py = {'a': 1, 'b': 2}
py.pop('a')  # 1
py.popitem()  # ('b', 2)
py.pop(123)  # raises KeyError
py.pop(123, 45)  # 45
var js = new Dict({'a': 1, 'b': 2});
js.pop('a');  // 1
js.popitem(); // ['b', 2]
js.pop(123);  // throws DictKeyNotFound
js.pop(123, 45);  // 45

Clearing out all key-value pairs

py = {'a': 1, 'b': 2}
len(py)  # 2
py.clear()
len(py)  # 0
py['a']  # raises KeyError
var js = new Dict({'a': 1, 'b': 2});
js.length();  // 2
js.clear();
js.length();  // 0
js.get('a');  // throws DictKeyNotFound

Forming a copy

py1 = {'a': 1, 'b': 2}
py2  = py1.copy()
py1['a'] = 987
py2['a']  # 1
var js1 = new Dict({'a': 1, 'b': 2});
var js2 = js1.copy();
js1.set('a', 987);
js2.get('a');  // 1

Updating key-value pairs

py = {'a': 1, 'b': 2}
py.update({'a': 999})
py['a']  # 999
len(py)  # 2
py.update([('b', 123)])
py['b']  # 123
var js = new Dict({'a': 1, 'b': 2});
js.update({'a': 999});
js.get('a');  // 999
js.length();  // 2
js.update([['b', 123]]);
js.get('b');  // 123

Iterating over keys, values, and items

py = {'a': 1}
# does not put all keys into memory at once
for key in py:
  print key  # prints 'a'
py.keys()  # ['a']

# does not put all values into memory at once
for value in py.itervalues():
  print value  # prints 1
py.values()  # [1]

# does not put all items into memory at once
for item in py.iteritems():
  print item  # prints ('a', 1)
py.items()  # [('a', 1)]
var js = new Dict({'a': 1});
// does not put all keys into memory at once
js.iterkeys(function(key) {
  console.log(key);  // logs 'a'
});
js.keys();  // ['a']

// does not put all values into memory at once
js.itervalues(function(value) {
  console.log(value);  // logs 1
});
js.values();  // [1]

// does not put all items into memory at once
js.iteritems(function(key, value) {
  console.log(key, value);  // logs 'a', 1
});
js.items();  // [['a', 1]]

Using non-Python methods

var js = new Dict();
js.isEmpty();  // true
js.set('key', 99);
js.isEmpty();  // false
// executes without putting all keys into a new array in memory
js.getFirstKey();  // 1
// executes without putting all keys into a new array in memory
js.getFirstMatchingKey(function(k) {
  return typeof(k) === 'number';
 });  // throws DictKeyNotFound
js.getFirstMatchingKey(function(k) {
  return typeof(k) === 'string';
});  // 'key'

// Since there is no direct access to stored elements,
// you can't do things like "py[123] += 1".
// This is especially true of keys whose values are primitive types:
// Boolean, String, or Number.
// Instead, you must do one of the following:
js.setOneNewValue('key', function(currentValue) {
  return currentValue + 10;
});
js.get('key');  // 109

js.setSomeNewValues(['key'], function(currentValue) {
  return currentValue + 10;
});
js.get('key');  // 119

js.setAllNewValues(function(currentValue) {
  return currentValue + 10;
});
js.get('key');  // 129

js.set('array key', []);
js.get('array key').push(123);
js.get('array key');  // [123]


DefaultDict

Static methods: same as Dict (DefaultDict is a subclass of Dict)

Instance methods: same as Dict

Demo

Creating a new DefaultDict

py = defaultdict(list)
py = defaultdict(int, a=1)
py = defaultdict(str, [('a', 1)])
py = defaultdict(int, dict(a=1))
py = defaultdict(123)  # raises TypeError
var js = new DefaultDict([].constructor);
var js = new DefaultDict(function(){return 0}, {'a': 1});
var js = new DefaultDict(String, [['a', 1]]);
var js = new DefaultDict(function(){return 0}, new Dict({'a': 1}));
var js = new DefaultDict(123);  // throws Error

Getting a potentially-missing key's value

py = defaultdict(int)
len(py)  # 0
py[1]  # 0
len(py)  # 1
py.keys()  # [1]
py.get(123)  # None
len(py)  # 1
py.keys()  # [1]
var js = new DefaultDict(function(){return 0});
js.length();  // 0
js.get(1);  // 0
js.length();  // 1
js.keys();  // [1]
js.get(123, null);  // null
js.length();  // 1
js.keys();  // [1]

Operating on potentially-missing keys' values

py = defaultdict(list)
for letter in 'abc':
  py[letter].append(123)
py.items()  # [('a', [123]), ('b', [123]), ('c', [123])]
var js = new DefaultDict([].constructor);
'abc'.split('').forEach(function(letter) {
  js.get(letter).push(123);
});
js.items();  // [['a', [123]], ['b', [123]], ['c', [123]]]

DefaultDict of Dicts

py = defaultdict(dict)
py[123][0] = 9
nested_dict = py[123]
nested_dict[0]  # 9
var js = new DefaultDict(function(){return new Dict()});
js.get(123).set(0, 9);
var nestedDict = js.get(123);
nestedDict.get(0);  // 9

Fun with self-referencing

py = defaultdict(lambda: py)
py[1][1][2][3] = 123
len(py)  # 3
py[1] is py  # True
3 in py  # True
2 in py  # True
1 in py  # True
py[3]  # 123
var js = new DefaultDict(function(){return js});
js.get(1).get(1).get(2).set(3, 123);
js.length();  // 3
js.get(1) === js;  // true
js.hasKey(3);  // true
js.hasKey(2);  // true
js.hasKey(1);  // true
js.get(3);  // 123


Counter

Static methods: same as DefaultDict, with some changes

  • fromKeys() is not implemented (throws an error)
  • getIncrementor(incrementBy)

Instance methods: same as DefaultDict, plus some new ones

  • iterelements(cb)
  • elements()
  • subtract(iterable)
  • mostCommon(opt_n)
  • leastCommon(opt_n)

Demo

Creating a new Counter

py = Counter()
py = Counter(a=2, b=1)
py = Counter(['a', 'a', 'b'])
py = Counter(123)  # raises TypeError
var js = new Counter();
var js = new Counter({'a': 2, 'b': 1});
var js = new Counter(['a', 'a', 'b']);
var js = new Counter(123);  // throws Error

Counting distinct elements

py = Counter()
py.update(['a', 'a', 32, 'false', False, float('inf')])
py.items()  # [('a', 2), (32, 1), ('false', 1), (False, 1), (inf, 1)]
list(py.elements())  # ['a', 'a', 32, 'false', False, inf]
var js = new Counter();
js.update(['a', 'a', 32, 'false', false, NaN]);
js.items();  // [['a', 2], [32, 1], ['false', 1], [false, 1], [NaN, 1]]
js.elements();  // ['a', 'a', 32, 'false', false, NaN]

Increasing/decreasing counts

py = Counter(['a', 'b', 'b', 'c', 'c', 'c'])
py[99]  # 0
py['a']  # 1
py['b']  # 2
py['c']  # 3
py.update(['a', 'a', 'b'])
py['a']  # 3
py['b']  # 3
py[99]  # 0
py['c']  # 3

py.subtract({'a': 4})
py['a']  # -1
var js = new Counter(['a', 'b', 'b', 'c', 'c', 'c']);
js.get(99);  // 0
js.get('a');  // 1
js.get('b');  // 2
js.get('c');  // 3
js.update(['a', 'a', 'b'])
js.get('a');  // 3
js.get('b');  // 3
js.get(99);  // 0
js.get('c');  // 3

js.subtract({'a': 4})
js.get('a')  // -1

Getting the most common elements

py = Counter(['a', 'b', 'b', 'c', 'c', 'c'])
py.most_common(1)  # [('c', 3)]
py.most_common(2)  # [('c', 3), ('b', 2)]
py.most_common(99)  # [('c', 3), ('b', 2), ('a', 1)]
py.most_common()  # [('c', 3), ('b', 2), ('a', 1)]
var js = new Counter(['a', 'b', 'b', 'c', 'c', 'c']);
js.mostCommon(1);  // [['c', 3]]
js.mostCommon(2);  // [['c', 3], ['b', 2]]
js.mostCommon(99);  // [['c', 3], ['b', 2], ['a', 1]]
js.mostCommon();  // [['c', 3], ['b', 2], ['a', 1]]


OrderedDict

Static methods: same as Dict (it's a Dict subclass)

Instance methods: same as Dict

Demo

Creating a new OrderedDict

py = OrderedDict()
py = OrderedDict(a=1, b=2)
py = OrderedDict([('a', 1), ('b', 2)])
var js = new OrderedDict();
var js = new OrderedDict({a:1, b:2});
var js = new OrderedDict([['a', 1], ['b', 2]]);

Maintaining the order of keys and values

py = OrderedDict()
py['1st'] = 0
py['2nd'] = 1
py['3rd'] = 2
py.keys()  # ['1st', '2nd', '3rd']
py.values()  # [0, 1, 2]

py.pop('1st')  # 0
py.keys()  # ['2nd', '3rd']
py.values()  # [1, 2]

py['1st'] = 0
py.keys()  # ['2nd', '3rd', '1st']
py.values()  # [1, 2, 0]
var js = new OrderedDict();
js.set('1st', 0);
js.set('2nd', 1);
js.set('3rd', 2);
js.keys();  // ['1st', '2nd', '3rd']
js.values();  // [0, 1, 2]

js.pop('1st');  // 0
js.keys();  // ['2nd', '3rd']
js.values();  // [1, 2]

js.set('1st', 0);
js.keys();  // ['2nd', '3rd', '1st']
js.values();  // [1, 2, 0]


NamedTuple

Demo

Defining a new NamedTuple class

Py = namedtuple('Py', ['a', 'b'])
var Js = NamedTuple('Js', ['a', 'b']);

Creating instances of the new class

py = Py(1, 2)  #  Py(a=1, b=2)
py = Py(1)  # throws TypeError
py = Py(1, 2, 3)  # throws TypeError
var js = new Js(1, 2);
js.toString();  // "Js(a=1, b=2)"
var js = new Js(1);  // throws Error
var js = new Js(1, 2, 3);  // throws Error

Accessing an instance's properties directly

py = Py(1, [2, 3])
py.a  # 1
py.b  # [2, 3]
py[0]  # 1
py[1]  # [2, 3]

py.a = 123  # raises AttributeError
py[1] = 99  # raises TypeError
var js = new Js(1, [2, 3]);
js.a;  // 1
js.b;  // [2, 3]
js[0];  // 1
js[1];  // [2, 3]

js.a = 99;  // throws Error in strict mode, otherwise changes nothing
js[1] = 99;  // changes nothing

Accessing an instance's properties via Array functions

py = Py(1, 2)
for value in py:
  print value  # prints 1 then 2
all(py)  # True
var js = new Js(1, 2);
js.forEach(function(value, index) {
  console.log(value, index);  // logs [1, 0] then [2, 1]
});
js.every(function(v){return v > 0});  // true

Package Sidebar

Install

npm i pycollections

Weekly Downloads

21

Version

0.9.1

License

MIT

Unpacked Size

42.9 kB

Total Files

5

Last publish

Collaborators

  • seriesoftubes