Giter VIP home page Giter VIP logo

mogkit's Introduction

MogKit

Build Status Carthage compatible Pod Information

MogKit is a toolkit that provides fully tested and easily composable transformations to collections and any series of values (like signals, channels, etc). The transformations are independant of the underlying values or data structures which makes them highly reusable.

As opposed to similar transformation frameworks MogKit works with composition instead of chaining which means the values are only iterated over once instead of once per step.

Use cases

There are several cases where using MogKit might make sense. Easiest shown with some example.

Simply transform data

When you simply want to transform some data in for example an array into a new array.

NSArray *array = @[@1, @2, @3];
NSArray *result = [array mog_transform:MOGMap(^id(NSNumber *number) {
    return @(number.intValue + 100);
});

// result is now @[@101, @102, @103]

Or work on some numbers and output as a string:

NSArray *array = @[@1, @2, @3];

NSString *result = MOGTransform(array, MOGStringConcatReducer(@", "), MOGCompose(MOGMap(^id(NSNumber *val) {
    return @(val.intValue + 10);
}), MOGMap(^id(NSNumber *val) {
    return val.stringValue;
})));

// result = "11, 12, 13"

It can also be used on any NSObject like:

id object = @10;
NSArray *expected = @[@(-10), @0, @10];

NSArray *result = [object mog_transform:MOGFlatMap(^id(NSNumber *number) {
    return @[@(-number.intValue), @0, number];
}) reducer:MOGArrayReducer()];

// result = @[@(-10), @0, @10]

Use to easily implement some transformation functions

Another case is when you have some data structure and want to add a transformation method to it, for example extending NSArray and give it a filter method, all you need to do is

@implementation NSArray (Filterable)

- (NSArray *)filter:(MOGPredicate)predicate
{
    return [self mog_transform:MOGFilter(predicate)];
}

@end

Combine to create new transformations

Say you want to add a trim: method to NSArray that returns a new array with trimSize elements removed from the start and end.

- (NSArray *)trim:(NSUInteger)trimSize 
{
    return [self mog_transform:MOGCompose(MOGDrop(trimSize), MOGTake(self.count - 2 * trimSize))];
}

Non-collection use cases

Using MogKit isn't limited to containers implementing NSFastEnumeration. You can easily make use of it to add composable transformation to anything where you want to transform a set of values. Here is an example adding a -mog_transform: method to RACStream (from ReactiveCocoa) in order to apply the passed in transformation to all values on the stream. This can be used instead of chaining a several of RACStreams built in transformations.

@implementation RACStream (MogKit)

- (instancetype)mog_transform:(MOGTransformation)transformation
{
    Class class = self.class;

    MOGTransformation transformationWithMapToRAC = MOGCompose(transformation, MOGMap(^id(id val) {
        return [class return:val];
    }));

    MOGReducer *reducer = transformationWithMapToRAC(MOGArrayReducer());

    return [[self bind:^{
        return ^(id value, BOOL *stop) {
            id acc = reducer.reduce(reducer.initial(), value, stop);
            if (*stop) {
                acc = reducer.complete(acc);
            }
            return [class concat:acc];
        };
    }] setNameWithFormat:@"[%@] -mog_transform:", self.name];
}

@end

This can later be used to apply a transformation to all values in a channel like this:

NSNumberFormatter *currencyFormatter = [NSNumberFormatter new];
currencyFormatter.numberStyle = NSNumberFormatterCurrencyStyle;

MOGTransformation add100ToIntValuesAndFormatAsCurrency = MOGComposeArray(@[
    MOGFilter(StringIsValidInt()),
    MOGMap(^id(NSString *string) {
        return @([string intValue] + 100);
    }),
    MOGMap(^id(id val) {
        return [currencyFormatter stringFromNumber:val];
    })
]);

[[textField.rac_textSignal mog_transform:add100ToIntValuesAndFormatAsCurrency] subscribeNext:^(id x) {
    NSLog(@"Number plus 100 = %@", x);
}];

The transformation can then be reused and is not even tied to RACStream.

Implemented Transformations

  • Map
  • Filter
  • Remove
  • Take
  • TakeWhile
  • TakeNth
  • Drop
  • DropWhile
  • DropNil
  • Replace
  • ReplaceWithDefault
  • MapDropNil
  • Unique
  • Dedupe
  • Flatten
  • FlatMap
  • PartitionBy
  • Partition
  • Window

Installation

Carthage

The easiest way is to install through Carthage. Simply add

github "mhallendal/MogKit"

to your Cartfile and follow the Carthage instructions for including the framework in your application.

CocoaPods

Alternatively by using CocoaPods, simply add

pod 'MogKit'

to your Podfile.

Submodule

You can also add it as submodule to your project https://github.com/mhallendal/MogKit.git and include the project file in your application.

If you are using the Foundation extensions, like -mog_transform: on NSArray, make sure that you add -ObjC to your application's Other Linker Flags.

TODO

  • Swift support (post 1.0)

Status

The API is still not locked down so might change slightly until 1.0 has been released.

This looks like Transducers

For a reader that are familiar with Transducers this will feel familiar, MogKit is implemented using Transducers and MOGTrasformations are actually transducers mapping from MOGReducer to MOGReducer.

For an introduction to transducers, see Clojure - Transducers and the presentation by Clojure creator Rich Hickey.

mogkit's People

Contributors

hallski avatar jensayton avatar mhallendal avatar rhult avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.