Have you ever thought about immutable version of Array.prototype
methods?
For example, Array.prototype.push
return a new Array
instead of number of items.
I've created immutable-array-prototype package.
Why immutable?
ECMAScript Array has some mutable methods.
For example, Redux require Immutable Update on your Store implementation.
Object.assign
or object spread({ ...object }
) can realize immutable updating for Object. But, immutale updating on Array is difficult.
Of course, Immutable.js is useful. But Immutable.js is very large library.
So, I want to get minimal and easy to use library.
@immutable-array/prototype
@immutable-array/prototype
includes immutable version of theses Array.prototype
methods.
npm install @immutable-array/prototype
Or, If you want to a single method, you can use a method as independent package.
npm install @immutable-array/pop
npm install @immutable-array/push
npm install @immutable-array/shift
npm install @immutable-array/unshift
npm install @immutable-array/sort
npm install @immutable-array/reverse
npm install @immutable-array/fill
npm install @immutable-array/splice
npm install @immutable-array/copy-within
Example
This library provide same API and behavior without first argument.
import {
sort,
unshift,
push,
fill,
splice,
pop,
reverse,
copyWithin,
shift
} from '@immutable-array/prototype';
describe('prototype', () => {
it('shift', () => {
assert.deepStrictEqual(shift(['a', 'b', 'c', 'd', 'e']), [
'b',
'c',
'd',
'e'
]);
});
it('unshift', () => {
assert.deepStrictEqual(unshift(['a', 'b', 'c', 'd', 'e'], 'x'), [
'x',
'a',
'b',
'c',
'd',
'e'
]);
});
it('pop', () => {
assert.deepStrictEqual(pop(['a', 'b', 'c', 'd', 'e']), [
'a',
'b',
'c',
'd'
]);
});
it('push', () => {
assert.deepStrictEqual(push(['a', 'b', 'c', 'd', 'e'], 'x'), [
'a',
'b',
'c',
'd',
'e',
'x'
]);
});
it('splice', () => {
assert.deepStrictEqual(splice(['a', 'b', 'c', 'd', 'e'], 0, 1, 'x'), [
'x',
'b',
'c',
'd',
'e'
]);
});
it('sort', () => {
assert.deepStrictEqual(sort(['e', 'a', 'c', 'b', 'd']), [
'a',
'b',
'c',
'd',
'e'
]);
});
it('reverse', () => {
assert.deepStrictEqual(reverse(['a', 'b', 'c', 'd', 'e']), [
'e',
'd',
'c',
'b',
'a'
]);
});
it('fill', () => {
assert.deepStrictEqual(fill(new Array(5), 'x'), ['x', 'x', 'x', 'x', 'x']);
});
it('copyWithin', () => {
assert.deepStrictEqual(copyWithin(['a', 'b', 'c', 'd', 'e'], 0, 3, 4), [
'd',
'b',
'c',
'd',
'e'
]);
});
});
Use Case
Faao that is GitHub Issue application use @immutable-array/prototype
for creating domain model.
Faao apply DDD/CQRS pattern using Almin. Immutable domain model help to work application in safety.
Policy
@immutable-array/prototype
has a support policy.
Do
- Provide immutable version of
Array.prototype
method - Provide each method as an module
- For exaple,
import push from "@immutable-array/push"
- All prototype method:
import { push } from "@immutable-array/prototype"
- For exaple,
- ECMAScript compatible API without first arguments
For example, @immutable-array/*
method should return same result with native API.
import { splice } from '@immutable-array/splice';
var array = [1, 2, 3];
// immutable
var resultArray = splice(array, -1, 1, 'x');
// native
array.splice(-1, 1, 'x');
assert.deepStrictEqual(array, resultArray);
Do not
- Should not add non-standard method in ECMAScript
- For example, It does not provide
update
,delete
,merge
methods.
- For example, It does not provide
- Each method should not depended on other method
Finally
Pull requests and stars are always welcome :)
Top comments (1)
pop
,push
,shift
,unshift
, andsplice
are not, and never were intended to be, immutable methods. The intended use of these is to allow JavaScript arrays to emulate a Stack or Queue object without needing to actually define a separate object in the language. Notably,pop
,shift
, andsplice
return the element(s) removed from the array, if any, so that they can be used in certain kinds of loops, i.e.:Now, this is a rather simplistic example, but when trying to navigate the layers of a tree in a dynamic fashion (rather than using recursion), the pattern becomes very useful:
Your immutable replacements for this would not be usable in this case as they are now.
I would suggest that your immutable replacements for these functions return an array consisting of the new array in the first element and then what the result of the non-immutable original function would be in the second element, e.g.: