EzDevInfo.com

ramda

<img class="emoji" title=":ram:" alt=":ram:" src="https://assets-cdn.github.com/images/icons/emoji/unicode/1f40f.png" height="20" width="20" align="absmiddle"> Practical functional Javascript

Refactoring out functional differences in complex calculations in Ramda

I'm just starting to play with Ramda a bit, and I'm relatively new to functional programming in general. I'm starting to get the hang of how to structure my programs, but I keep getting hung up on a certain aspect. I feel that I must be missing some key concept.

I'm not even certain of how to word my question, so I am going to start with an example. This code snippet is a portion of the calculation for the centroid of an arbitrary polygon:

var centroidX = R.converge(
                    R.divide,
                    R.compose(
                        R.sum,
                        R.map(
                            R.converge(
                                R.multiply,
                                R.converge(R.add, x1, x2),
                                diffOfProducts
                            )
                        ),
                        makeVertexPairs
                    ),
                    sixTimesPolyArea
                );
var centroidY = R.converge(
                    R.divide,
                    R.compose(
                        R.sum,
                        R.map(
                            R.converge(
                                R.multiply,
                                R.converge(R.add, y1, y2),
                                diffOfProducts
                            )
                        ),
                        makeVertexPairs
                    ),
                    sixTimesPolyArea
                );
Geom.centroid = R.curry(function(vertices) {
                    return [ centroidX(vertices), centroidY(vertices) ];
                });

Notice that the only difference between centroidX and centroidY is that the X coordinate calls x1 and x2 near the middle, and the Y coordinate calls y1 and y2 near the middle.

Is there some simple way to refactor out this commonality such that I can do something like the following:

var centroidCoord = R.converge(
                    R.divide,
                    R.compose(
                        R.sum,
                        R.map(
                            R.converge(
                                R.multiply,
                                R.converge(R.add, R.__, R.__),
                                diffOfProducts
                            )
                        ),
                        makeVertexPairs
                    ),
                    sixTimesPolyArea
                );
Geom.centroid = R.curry(function(vertices) {
                    return [ centroidX(x1, x2, vertices), centroidY(y1, y2, vertices) ];
                });

I know that this isn't even close. I'm just trying to express what I want to accomplish. Any recommendations?


Source: (StackOverflow)

Is there something similar to lodash _.toArray for ramda.js?

I want to stop using lodash.js and switch to ramda.js but I don't see any function like _.toArray() for objects, is there something like this in ramda that I should compose or should I continue using lodash for these functions (and possibly more cases that I have not run into yet.)

For example In lodash if you have an Object like :

{"key1": {"inner": "val"}, "key2" : {"inner": "val"}}

you can convert it to an array like this:

[{"inner": "val"}, {"inner": "val"}]

using the function _.toArray()


Source: (StackOverflow)

Advertisements

How can i do this better with Ramda.js

So I have a list of divs: list

i want a subset of the list removing the divs with the .fade class. and also just grabbing the list from the div with .selected class.

so using R.takeWhile and R.dropWhile.

then i want to map over that new list and add a .active class on a subset of that list with R.take and R.forEach or R.map

something like :

var takeFromSelected = R.dropWhile(function(item){!$(item).hasClass('selected')};

var removeFadeItems = R.takeWhile(function(item){!$(item).hasClass('fade')});

var addActiveClass = function(x){ $(x).addClass('.active')};

var processList = R.pipe(R.map(addActiveClass), removeFadeItems, takeFromSelected);

processList(list);

Im really new to this FP stuff and trying to get the grip of it.

Any insight would be greatly apreciated!! Thanks! :)

Update

for future reference this is what i did :

@addActiveClass = (x)->  
  $(x).addClass('active') 
  return

@takeFromSelected = R.dropWhile((item)-> !$(item).hasClass('selected'))

@removeFadeItems = R.takeWhile((item)-> !$(item).hasClass('fade'))

@addWeekView = R.compose(addActiveClass, removeFadeItems, takeFromSelected)

Source: (StackOverflow)

How can I compose a function so that an inner application implicitly receives an outer argument? [duplicate]

This question already has an answer here:

EDIT: I've marked this as a duplicate of Can I make this function defenition [sic] even shorter?, which is functionally identical (two puns intended) and has a good answer from one of the authors of the Ramda library.

This is a question more of academic curiosity than practical need.

I'm trying out the Ramda library, which emphasises a "point-free" style of function composition.

Suppose I have an array of objects, like

var things = [
    {id: "a", value: 234},
    {id: "b", value: 345},
    {id: "c", value: 456}
]

and I wanted a function to return the element by id (or at least, for the moment, a list matching by id). In native javascript, I can say

var byId = function(id, arr) { return arr.filter(function(o) { return o.id === id; }); };

then byId('c', things) will give me an array containing just the third item.

In Ramda, I can do this more concisely and with no reference to the data:

var byIdRam = function(id) { return R.filter(R.propEq('id', id)); }

The result is a "curried" function, so byIdRam('c')(things) gives the same result as the first version.

I sense that the remaining lambda is also unnecessary, but I don't know how to compose the function without explicit reference to the id. Does anyone know a better way to write this?

UPDATE The answer is simply

var byId = R.useWith(R.find, R.propEq('id'))

This also gives the semantics I want, where it either returns a single element or undefined. Nice!


Source: (StackOverflow)

Ramda does not provide deep mixin?

var _ = require('ramda');

var obj1 = {
    innerNum: 1,
    innerObj: {
        innerStr: 'a',
        innerStrB: 'Z'
    }
};

var obj2 = {
    innerNum: 2,
    innerObj: {
        innerStr: 'b'
    }
};

var mixedObj = _.mixin(obj1, obj2);

mixedIObj does not include the inner object's innerStrB. Any ramda solution?


Source: (StackOverflow)

Ramda ifElse behaving strangely

Why when I run the ifElse method here does false log "function two (onTruthy)"?

var x = R.ifElse(R.T, function(){
  console.log("function two (onTruthy)")
  // console.log(arguments)
}, function(){
  console.log("function three (onFalsy)")
  // console.log(arguments)
})
x(false)

I'm thinking it's because R.T is always returning true. Perhaps using _.isMatch I can match it?

Update: Just tried:

var x = R.pipe(
  R.partialRight(R.match, true),
  R.partialRight(R.ifElse, function(){
    console.log("function two (onTruthy)")
    // console.log(arguments)
  }, function(){
    console.log("function three (onFalsy)")
    // console.log(arguments)
  })
)

Source: (StackOverflow)

Two dimensional array mapping in point free notation?

I'm playing around with functional/tacit style programming, specifically creating the snake game (example of game: http://patorjk.com/games/snake/)

The specific question is that I'm taking an array of strings like:

[
 ['2 '],
 ['10']
]

and wanting to get the list of coordinates in numerical order of the 'value'. In the domain, 0 is the head of the snake, 2 is the tail, the whole thing is the board.

So I built:

var findSnake = function(rendered_board) {
  return r.map(function(x) {
    return r.map(function (y) {
      return {
        x: x,
        y: y,
        val: rendered_board[x][y]
      };
    })(r.keys(r.split('', rendered_board[x])));
  })(r.keys(rendered_board));
};

which gives me back:

[ [ { x: '0', y: '0', val: '2' }, { x: '0', y: '1', val: ' ' } ], [ { x: '1', y: '0', val: '1' }, { x: '1', y: '1', val: '0' } ] ] which I can then sort and get my list of coordinates. It works but I have questions on style.

Is there a way to write findSnake in point free style? Is there a more idiomatic approach to this problem?


Source: (StackOverflow)

Ramda: How to filter based on a value in a nested array

I'm trying to accomplish this in a functional manner (with Ramda). My JSON is structured like this

[
    {username: 'bob', age: 30, tags: ['work', 'boring']},
    {username: 'jim', age: 25, tags: ['home', 'fun']},
    {username: 'jane', age: 30, tags: ['vacation', 'fun']}
]

and I am trying to filter based on a value in the 'tags' property, but have not been successful. I am able to filter on ints/strings (age and username), but I can't figure out how to do so with values in nested arrays (tags). Any help would be much appreciated.


Source: (StackOverflow)

Map into an object without a temporary variable

How do I map through array of objects and based on that create another object (based on element properties), without temporary object? So if I have something like:

 foos = [ { name: 'A' }, { name: 'B' }, { name: 'C' } ]
 objx = {}
 foos.map (x)-> 
     objx[x.name] = 'name is ' + x.name.toLowerCase()

 # objx = { A: 'name is a', B: 'name is b', C: 'name is c' }

How can I accomplish the same thing without objx thing? Either with or without using whatever helper library - lodash, ramda, jquery, angular, etc.


Source: (StackOverflow)

Typescript definition of function with property

I'm writing a d.ts file for ramda. The lib has a function mapObj and mapObj.idx.

interface RamdaStatic {
 ...
  mapObj(
    fn: Function,
    obj: any
  ): any;
  ...
}

My question is how to add mapObj.idx that has a similar type def? I am aware of answer, but that requires a seperate interface and I would like to avoid that.


Source: (StackOverflow)

What's Ramda equivalent to underscore.js 'compact'?

Does Ramda have a function to remove false values from a list?

I know we can simply do var compact = R.filter(R.identity); but am I missing the ready-made function?


Source: (StackOverflow)

Circular dependencies of EventStreams in FRP

All examples uses Ramda as _ (it's clear what methods do in examples contexts) and kefir as frp (almost same API as in bacon.js)

I have a stream, that describes change of position.

var xDelta = frp
    .merge([
        up.map(_.multiply(1)),
        down.map(_.multiply(-1))
    ])
    .sampledBy(frp.interval(10, 0))
    .filter();

It emits +1 when I press UP key, and -1 on DOWN.

To get position I scan this delta

var x = xDelta
    .scan(_.add)
    .toProperty(0);

That's work as expected. But I want to limit value of x from 0 to 1000.

To solve this problem I found two solution:

  1. Change function in scan

    var x = xDelta.scan(function (prev, next) {
        var newPosition = prev + next;
        if (newPosition < 0 && next < 0) {
            return prev;
        }
        if (newPosition > 1000 && next > 0) {
            return prev;
        }
        return newPosition;
    }, 0);
    

It looks Ok, but later, as new rules will be introduced, this method will grow. So I mean it doesn't look composable and FRPy.

  1. I have current position. And delta. I want to apply delta to current, only if current after applying will not be out of limits.

    • current depends on delta
    • delta depends on current after applying
    • current after applying depends on current

    So it looks like circular dependency. But I solved it using flatMap.

    var xDelta = frp
        .merge([
            up.map(_.multiply(1)),
            down.map(_.multiply(-1))
        ])
        .sampledBy(frp.interval(10, 0))
        .filter();
    
    var possibleNewPlace = xDelta
        .flatMap(function (delta) {
            return x
                .take(1)
                .map(_.add(delta));
        });
    
    var outOfLeftBoundFilter = possibleNewPlace
        .map(_.lte(0))
        .combine(xDelta.map(_.lte(0)), _.or);
    
    var outOfRightBoundFilter = possibleNewPlace
        .map(_.gte(1000))
        .combine(xDelta.map(_.gte(0)), _.or);
    
    var outOfBoundFilter = frp
        .combine([
            outOfLeftBoundFilter,
            outOfRightBoundFilter
        ], _.and);
    
    var x = xDelta
        .filterBy(outOfBoundFilter)
        .scan(_.add)
        .toProperty(0);
    

    You can see full code example at iofjuupasli/capture-the-sheep-frp

    And it's working demo gh-pages

    It works, but using circular dependencies is probably anti-pattern.

Is there a better way to solve circular dependency in FRP?

The second more general question

With Controller it's possible to read some values from two Model and depending on it's values update both of them.

So dependencies looks like:

              ---> Model
Controller ---|
              ---> Model

With FRP there is no Controller. So Model value should be declaratively calculated from other Model. But what if Model1 calculating from another Model2 which is the same, so Model2 calculates from Model1?

Model ----->
      <----- Model

For example two players with collision detection: both players have position and movement. And movement of first player depends on position of second, and vice versa.

I'm still newbie in all this stuff. It's not easy to start think in declarative FRP style after years of imperative coding. Probably I'm missing something.


Source: (StackOverflow)

How to rewrite this in terms of R.compose

var take = R.curry(function take(count, o) {
    return R.pick(R.take(count, R.keys(o)), o);
});

This function takes count keys from an object, in the order, in which they appear. I use it to limit a dataset which was grouped.

I understand that there are placeholder arguments, like R.__, but I can't wrap my head around this particular case.


Source: (StackOverflow)

ramda equivalent for rotate

Given a rotate function like the one below, which rotates the array a set number of slots.

Is there an equivalent Ramda.js function or composition that will do this rotation?

var test = [1,2,3,4,5,6,7,8,9];
function rotate(arr, count) {
    arr = arr.slice();
    while (count < 0) {
      count += arr.length;
    }
    count %= arr.length;
    if (count) {
      arr.splice.apply(arr, [0, 0].concat([].slice.call(arr.splice(arr.length - count, count))));
    }
    return arr;
}

example

rotate(test, 2) // -> [8, 9, 1, 2, 3, 4, 5, 6, 7]

Source: (StackOverflow)