Skip to content

A NativeScript module providing LINQ style extensions for handling arrays and lists.

License

Notifications You must be signed in to change notification settings

mkloubert/nativescript-enumerable

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

95 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

npm npm

NativeScript Enumerable

A NativeScript module providing LINQ style extensions for handling arrays and lists.

Donate

NativeScript Toolbox

This module is part of nativescript-toolbox.

License

MIT license

Platforms

  • Android
  • iOS

Installation

Run

tns plugin add nativescript-enumerable

inside your app project to install the module.

Usage

Create a sequence

import Enumerable = require("nativescript-enumerable");

// from a list of values / objects with variable length
var seq1 = Enumerable.create(1, 'MK', true, null, {});

// from an array / list
var seq2 = Enumerable.fromArray([11, 22, 33, 44]);

// from object
var seq3 = Enumerable.fromObject({
    MK: 23979,
    TM: 5979
});

// range of numbers: 2, 3, 4, 5, 6
var seq4 = Enumerable.range(2, 5);

// 50979 'TM' strings
var seq5 = Enumerable.repeat('TM', 50979);

Work with them

var seq = Enumerable.create(5979, 23979, null, '23979', 1781, 241279);

var newSeq = seq.where((x) => x !== null)  // remove all elements that are (null)
                .skip(1)  // skip one element (5979)
                .take(3)  // take next remaining 3 elements (23979, 23979, 1781)
                .distinct()  // remove duplicates
                .select((x) => "" + x)  // convert to strings
                .order();  // order by element ascending

newSeq.each((item) => {
    // [0] 1781
    // [1] 23979
    console.log(item);
});

Most methods are chainable as in .NET context.

Functions and lambda expression

Many methods require one or more function.

Instead using a function like

.where(function(x) {
           return x !== null;
       })

you can write

.where('x => x !== null')

instead.

Documentation

The full documentation with all functions and methods can be found on readme.io.

Demo app

The demo app contains examples to all functions and methods.

It also contains a code editor where you can enter own code and run it!

The wiki describes how it works.

Examples

Filters

// distinct()
// 1, 2, 4, 3
Enumerable.create(1, 2, 4, 2, 3)
          .distinct();
 
// except()
// 2.0, 2.1, 2.3, 2.4, 2.5
Enumerable.create(2.0, 2.1, 2.2, 2.3, 2.4, 2.5)
          .except([2.2]); 
 
// intersect()
// 26, 30
Enumerable.create(44, 26, 92, 30, 71, 38)
          .intersect([30, 59, 83, 47, 26, 4, 3]);
       
// ofType()
// '2', 'Tanja'
Enumerable.create(1, '2', 2, 'Tanja', 3)
          .ofType('string');  // typeof x == 'string'
          
// union()
// 5, 3, 9, 7, 8, 6, 4, 1, 0
Enumerable.create(5, 3, 9, 7, 5, 9, 3, 7)
          .union([8, 3, 6, 4, 4, 9, 1, 0]);
          
// where()
// 1, 2, 3
Enumerable.create(1, 2, 3, 4)
          .where((x) => x < 4);

Sort elements

// orderBy(), thenBy()
//
// "apple", "grape", "mango", "banana",
// "orange", "blueberry", "raspberry", "passionfruit"
Enumerable.create("grape", "passionfruit", "banana", "mango", 
                  "orange", "raspberry", "apple", "blueberry")
          .orderBy((x) => x.length)  // complement: orderByDescending()
          .thenBy((x) => x);  // complement: thenByDescending()
                              // shorter: then()

// reverse()
// 4, 3, 2, 1
Enumerable.create(1, 2, 3, 4)
          .reverse();

Take / skip elements

// skip()
// 3, 4
Enumerable.create(0, 1, 2, 3, 4)
          .skip(3);

// skipLast()
// 0, 1, 2, 3
Enumerable.create(0, 1, 2, 3, 4)
          .skipLast();
          
// skipWhile()
// 55, 666, 77
Enumerable.create(22, 33, 44, 55, 666, 77)
          .skipWhile((x) => x < 50);
          
// take()
// 0, 1, 2
Enumerable.create(0, 1, 2, 3, 4)
          .take(3);

// takeWhile()
// 22, 33, 44
Enumerable.create(22, 33, 44, 55)
          .takeWhile((x) => x < 50);

Get one element

// elementAt()
// 33
Enumerable.create(11, 22, 33, 44)
          .elementAt(2);
          
// elementAtOrDefault()
// 'TM'
Enumerable.create(11, 22, 33, 44)
          .elementAtOrDefault(4, 'TM');  // out of range
          
// first()
// 11
Enumerable.create(11, 22, 33, 44)
          .first();
          
// firstOrDefault()
// 'MK'
Enumerable.create()
          .firstOrDefault('MK');
          
// last()
// 44
Enumerable.create(11, 22, 33, 44)
          .last();
          
// lastOrDefault()
// 'PZ'
Enumerable.create()
          .lastOrDefault('PZ');

// single()
// EXCEPTION, because we have more than one element
Enumerable.create(11, 22, 33, 44)
          .single();
          
// singleOrDefault()
// 11
Enumerable.create(11)
          .singleOrDefault('YS');

All methods with NO OrDefault suffix will throw exceptions if no element was found.

You also can use a function as first argument for all of these methods that works as filter / condition:

// first()
// 22
Enumerable.create(11, 22, 33, 44)
          .first((x) => x >= 20);

Accumulators

// aggregate()
// "Marcel Joachim Kloubert"
Enumerable.create('Marcel', 'Joachim', 'Kloubert')
          .aggregate((result: string, x: string) => {
                         return result += " " + x;
                     });

// average()
// 2.5
Enumerable.create(1, 2, 3, 4)
          .average();
          
// sum()
// 10
Enumerable.create(1, 2, 3, 4)
          .sum();  

Minimum / maximum values

// max()
// 3
Enumerable.create(1, 3, 2)
          .max(); 
          
// min()
// 1
Enumerable.create(2, 3, 1, 2)
          .min();

Joins

class Person {
    constructor(name: string) {
        this.name = name;
    }

    public name: string;
}

class Pet: {
    constructor(name: string, owner: Person) {
        this.name = name;
        this.owner = owner;
    }

    public name: string;
    public owner: Person;
}

var persons: Person[] = [
    new Person("Tanja"),
    new Person("Marcel"),
    new Person("Yvonne"),
    new Person("Josefine")
];

var pets: Pet[] = [
    new Pet("Gina", persons[1]),
    new Pet("Schnuffi", persons[1]),
    new Pet("Schnuffel", persons[2]),
    new Pet("WauWau", persons[0]),
    new Pet("Lulu", persons[3]),
    new Pet("Asta", persons[1]),
];

// groupJoin()
// 
// [0] 'Owner: Tanja; Pets: WauWau, Sparky'
// [1] 'Owner: Marcel; Pets: Gina, Schnuffi, Asta'
// [2] 'Owner: Yvonne; Pets: Schnuffel'
// [3] 'Owner: Josefine; Pets: Lulu'
Enumerable.fromArray(persons)
          .groupJoin(pets,
                     (person: Person) => person.name,
                     (pet: Pet) => pet.owner.name,
                     (person: Person, petsOfPerson: Enumerable.IEnumerable<Pet>) => {
                         var petList = petsOfPerson
                             .select((pet: Pet) => pet.name)
                             .aggregate((result: string, petName: string) => {
                                            return result += ", " + petName;
                                        });
                     
                         return 'Owner: ' + person.name + '; Pets: ' + petList;
                     });

// join()
// 
// [0] 'Owner: Tanja; Pet: WauWau'
// [1] 'Owner: Marcel; Pet: Gina'
// [2] 'Owner: Marcel; Pet: Schnuffi'
// [3] 'Owner: Marcel; Pet: Asta'
// [4] 'Owner: Yvonne; Pet: Schnuffel'
// [5] 'Owner: Josefine; Pet: Lulu'
Enumerable.fromArray(persons)
          .join(pets,
                (person: Person) => person.name,
                (pet: Pet) => pet.owner.name,
                (person: Person, pet: Pet) => {
                    return 'Owner: ' + person.name + '; Pet: ' + pet.name;
                });

Groupings

// groupBy()
Enumerable.create("grape", "passionfruit", "banana",
                  "apple", "blueberry")
          .groupBy((x: string) => x[0])
          .each(function(grouping: Enumerable.IGrouping<string, string>) {
                    // grouping[0].key = 'g'
                    // grouping[0][0] = 'grape'
                    
                    // grouping[1].key = 'p'
                    // grouping[1][0] = 'passionfruit'
                    
                    // grouping[2].key = 'b'
                    // grouping[2][0] = 'banana'
                    // grouping[2][1] = 'blueberry'
                    
                    // grouping[3].key = 'a'
                    // grouping[3][0] = 'apple'
                });

Projection

// select()
// "MARCEL", "KLOUBERT"
Enumerable.create("Marcel", "Kloubert")
          .select((x: string) => x.toUpperCase());
          
// selectMany()
// 1, 10, 100, 2, 20, 200, 3, 30, 300
Enumerable.create(1, 2, 3)
          .selectMany((x: number) => [x, x * 10, x * 100]);

// zip()
// "Marcel Kloubert", "Bill Gates", "Albert Einstein"
Enumerable.create('Marcel', 'Bill', 'Albert')
          .zip(['Kloubert', 'Gates', 'Einstein', 'Adenauer'],
               (firstName: string, lastName: string) => {
                   return firstName + " " + lastName;
               });

Checks / conditions

// all()
// (false)
Enumerable.create(1, 2, '3', 4)
          .all((x) => typeof x !== "string");
          
// contains()
// (true)
Enumerable.create(1, 2, '3')
          .contains(3);

// any()
// (true)
Enumerable.create(1, 2, '3', 4)
          .any((x) => typeof x === "string");
 
// sequenceEqual()
// (false)         
Enumerable.create([1, 2, 3])
          .sequenceEqual([1, 3, 2]);

Conversions

// toArray()
var jsArray = Enumerable.create(1, 2, 3, 4)
                        .toArray();
  
// toObject()
var obj = Enumerable.create(1, 2, 3, 4)
                    .toObject((item, index) => "item" + index);  
  
// toObservable()
var o = Enumerable.create(1, 2, 3, 4)
                  .toObservable((item, index) => "item" + index);
  
// toObservableArray()
var oa = Enumerable.create(1, 2, 3, 4)
                   .toObservableArray();  
  
// toLookup()
// 
// lookup['A'][0] = 'Albert'
// lookup['B'][0] = 'Bill'
// lookup['B'][1] = 'Barney'
// lookup['K'][0] = 'Konrad'
// lookup['M'][0] = 'Marcel'
var lookup = Enumerable.create('Bill', 'Marcel', 'Barney', 'Albert', 'Konrad')
                       .toLookup((x: string) => x[0]);

Count

// 3
Enumerable.create(0, 1, 2)
          .count();
          
// 2
Enumerable.create(0, 1, 2)
          .count((x) => x > 0);

More

concat

// 0, 1, 2, 'PZ', 'TM', 'MK'
Enumerable.create(0, 1, 2)
          .concat(['PZ', 'TM', 'MK']);

defaultIfEmpty

// 0, 1, 2
Enumerable.create(0, 1, 2)
          .defaultIfEmpty('PZ', 'TM', 'MK');
          
// 'PZ', 'TM', 'MK'
Enumerable.create()
          .defaultIfEmpty('PZ', 'TM', 'MK');

moveNext / current

var seq = Enumerable.create(0, 1, 2);
while (seq.moveNext()) {
    console.log(seq.current);
}

reset

var seq = Enumerable.create(0, 1, 2);

seq.each((x: number) => {
             console.log(x);
         });

seq.reset()
   .each((x: number) => {
             console.log(x * 2);
         });

About

A NativeScript module providing LINQ style extensions for handling arrays and lists.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published