es6-arraylist
TypeScript icon, indicating that this package has built-in type declarations

0.3.0 • Public • Published

ArrayList

Array-derived class taking advantage of ES6 built-in subclassing designed to provide facilities similar to those of Kotlin or Java's ArrayList. It's by no means as powerful, but has way more than just add, get and remove.

I apologize for the lack of testing and the incomplete readme. I'll update regularly until both of these things are finished.

Usage

Adding to your project

To install the package:

npm install es6-arraylist

Since this package is compatible with TypeScript, those using JS will have to require it accessing the export's default property:

//const ArrayList = require("es6-arrayList"); // wrong: { default: [class ArrayList extends Array] }
const ArrayList = require("es6-arraylist").default;

const myList = ArrayList.of(1, 2, 3); // ArrayList (3) [1, 2, 3]

Constructor

The constructor works very similarly to Array's built-in constructor. However, ArrayList's constructor also accepts a size and function or another Array (or ArrayList). Examples below.

const list1 = new ArrayList();              // []
const list2 = new ArrayList(5);             // [ empty x 5 ]
const list3 = new ArrayList(1, 2, 3, 4);    // [1, 2, 3, 4]
const list4 = new ArrayList(4, i => i * 2); // [0, 2, 4, 6]
const list5 = new ArrayList([1, 2, 3]);	    // [1, 2, 3]

For clarity purposes, there are also two other ways of creating ArrayLists from static functions available:

// Of creates an ArrayList from a variable amount of arguments.
const list1 = ArrayList.of(10);        // [10]
const list2 = ArrayList.of(1, 2, 3);   // [1, 2, 3]
const list3 = ArrayList.of([1, 2, 3]); // [[1, 2, 3]] beware!

// Iterate does the same as using the constructor with size and a function.
// It's just clearer in intent.
const list4 = ArrayList.iterate(4, i => i * 2); // [0, 2, 4, 6]

Adding and removing elements

There are several functions that serve this purpose with slight differences each.

Adding elements:

// Add is mutating. Returns the modified original list.
const list1 = new ArrayList(1, 2);
list1.add(3); // [1, 2, 3]

// Append is non mutating. Returns a modified copy of the original list.
const list2 = new ArrayList(1, 2);
const list2b = list2.append(3);
console.log(list2);  // [1, 2]
console.log(list2b); // [1, 2, 3]

// Insert adds elements at a specific index without overwriting any values. 
// Mutating.
const list3 = new ArrayList(2, 3);
list3.insert(0, 1); // [1, 2, 3]

// Set adds elements at a specific index, overwriting any values. Mutating.
const list4 = new ArrayList(1, 2, 4);
list4.set(2, 3); // [1, 2, 3]

Removing elements:

// Remove does exactly what you think it does. Mutating.
const list1 = new ArrayList(1, 2, 3, 4);
list1.remove(4); // [1, 2, 3]

// Alternatively, you can use an index to remove an item.
const list2 = new ArrayList(1, 2, 3, 4);
list2.removeFromIndex(3); // [1, 2, 3]
// By default, only 1 element is removed. You can define the amount:
const list3 = new ArrayList(1, 2, 3, 4, 5);
list3.removeFromIndex(3, 2); // [1, 2, 3]

// Difference is a non-mutating equivalent to remove.
// It expects an Array / ArrayList.
const list4 = new ArrayList(1, 2, 3, 4);
const list4b = list4.difference([ 4 ]);
console.log(list4);  // [1, 2, 3, 4]
console.log(list4b); // [1, 2, 3];

Retrieving items

const list = new ArrayList("first", "second", "third", "fourth", "last");

// If given no arguments, first returns the first element of the ArrayList.
list.first(); // "first"

// If, instead, provided a predicate, will return the first element 
// (using Array.find) that fulfills it:
list.first(s => s.length == 6); // "second"

// Similarly, if given no arguments, last will return the last element 
// of the ArrayList.
list.last(); // "last"
// With a predicate, it will return the last element that fulfills it, 
// using ArrayList.findLast():
list.last(s => s.length == 6); // "fourth"

// In case first / find / last / findLast fails finding the argument, 
// a defaultValue function can be specified.
list.first(s => s.length == 10,
           _ => "nothing found."); // "nothing found."

// At is just an implementation of Array.at() which is currently experimental.
// Returns undefined if the index is out of bounds.
list.at(1);  // "second"
list.at(-1); // "last"

// ElementAtOrElse allows for a custom return value in case the index is out of bounds.
list.elementAtOrElse(7, i => `nothing found at index ${i}`); // "nothing found at index 7"

// You can get the maximum and minimum values of an ArrayList using max and min:
const someNumbers = new ArrayList(1, 2, 3, 4, 5);
someNumbers.max(); // 5
someNumbers.min(); // 1
// If you have objects that can't be compared using standard greater or less than operators,
// you can define a default comparator and use maxBy and minBy:
const someObjects = new ArrayList({ name: "peter", age: 20 },
                                  { name: "monica", age: 23},
                                  { name: "marcelo", age: 19});
const ageFilter = person => person.age;
const oldest = someObjects.maxBy(ageFilter);   // { name: "monica", age: 23 }
const youngest = someObjects.minBy(ageFilter); // { name: "marcelo", age: 19 }

// To obtain random values from an ArrayList, you can use random and sample:
// Random returns one random element from the ArrayList.
const randomValue = someList.random();
// If one value is not enough, you can use sample and define a size:
const randomValues = someList.sample(3);

Checking for conditions

// Without arguments, any will check if there is at least one element
// in an ArrayList:
new ArrayList().any();        // false
new ArrayList(5).any();       // false, the Array has no keys
const list1 = new ArrayList(1, 2, 3).any(); // true

// If, instead, given a predicate, any will behave just like Array.some():
list1.any(n => n == 2); // true

// Contains and containsAll check if there is a particular item in
// an ArrayList. Uses the == operator.
const list4 = new ArrayList("wagner", "at", "the", "opera");
list4.contains("opera"); // true
list4.containsAll(["wagner", "opera"]); // true

// Equals uses the == operator to compare items on both arrays.
const list5 = new ArrayList("some", "strings");
const list6 = new ArrayList("some", "strings");
list5 === list6;     // false
list5 == list6;      // false
list5.equals(list6); // true

// IsEmpty checks if the array is empty. Duh.
new ArrayList().isEmpty(); // true

List operations

// MapNotFalsy and mapNotNull apply a transformator function on
// each item of the ArrayList, filtering out falsy and null values
// respectively:
const list1 = new ArrayList(2, 4, "c", "d", 10);
list1.map(n => n / 2);         // [1, 2, NaN, NaN, 5]
list1.mapNotFalsy(n => n / 2); // [1, 2, 5]

list1.map(n => typeof n === "number" ? n / 2); // [1, 2, undefined, undefined, 5]
list1.mapNotNull(n => typeof n === "number" ? n / 2); // [1, 2, 5]

// Zip returns an ArrayList of pairs created from elements of two arrays
// at the same index:
const list2 = new ArrayList("a", "b", 6, 8, "e");
list1.zip(list2); // [[2, "a"], [4, "b"], ["c", 6], ["d", 8], [10, "e"]]
// Note: Zip can also get a transformator function as a second argument.
// It should return a pair.

// If, instead, all elements are in the same array, you can use zipWithNext:
const list3 = new ArrayList(1, "a", 2, "b", 3, "c");
list3.zipWithNext(); // [[1, "a"], [2, "b"], [3, "c"]]

// Unzip allows us to turn a zipped ArrayList (list of pairs) into a pair of
// lists:
zipped.unzip(); // [[2, 4, "c", "d", 10], ["a", "b", 6, 8, "e"]]

Altering the list

I'm still writing this. University is awful. Sorry.

// Chunked splits an array into smaller chunks of custom size.
const list1 = new ArrayList(1, 2, 3, 4, 5);
list1.chunked(2); // [[1, 2], [3, 4], [5]]
list1.chunked(3); // [[1, 2, 3], [4, 5]]

// Drop and dropWhile remove the first n elements of an ArrayList.
// They're non mutating.
const list2 = new ArrayList("yadda", "yadda", "(", "inside", "parentheses", ")");
list2.drop(2);                  // ["(", "inside", "parentheses", ")"]
list2.dropWhile(s => s != "("); // ["(", "inside", "parentheses", ")"]

// Take, takeWhile and takeWhileLazy take the first n elements of an ArrayList.
// They're non mutating.
list2.take(2);                      // ["yadda", "yadda"]
list2.takeWhile(s => s != "(");     // ["yadda", "yadda"]
list2.takeWhileLazy(s => s != "("); // Generator

// FilterInstance, filterNotFalsy and filterNotNull filter out values:
class Person {
    constructor(name, age) {
        this.name = name;
    }
}
const people = new ArrayList(1, new Person("eren"),
                             2, new Person("mikasa"),
                             3, new Person("armin"));
// FilterInstance uses the instanceof operator, so it won't work on primitives.
people.filterInstance(Person); // [ { name: "eren" },
                               //   { name: "mikasa" },
                               //   { name: "armin"} ]

const list3 = new ArrayList(1, false, null, "hello", undefined);
list3.filterNotFalsy(); // [1, "hello"]
list3.filterNotNull();  // [1, false, "hello"]

// Reversed is a non-mutating alternative to Array.reverse:
list3.reversed(); // [undefined, "hello", null, false, 1]

// Shuffled shuffles. Go figure. Non mutating, by the way.
// For a mutating alternative, ArrayList.shuffle()
list3.shuffle();
list3.shuffled();

// Sorted is a non-mutating alternative to Array.sort():
const list4 = new ArrayList(1, 3, 5, 4, 2)
console.log(list4.sorted()); // [1, 2, 3, 4, 5]
console.log(list4);          // [1, 3, 5, 4, 2]

// Unique removes all repeated elements that are sanely comparable with standard
// algorithms. That means no objects. Sorry. Non mutating.
new ArrayList(1, 2, 3, 2, 4, 4, 5).unique(); // [1, 2, 3, 4, 5]

Converting to other data types

// associateWith, eachCount, fromPairs, groupBy, toArray, toSet

Package Sidebar

Install

npm i es6-arraylist

Weekly Downloads

9

Version

0.3.0

License

ISC

Unpacked Size

62.3 kB

Total Files

7

Last publish

Collaborators

  • maruseron