jskulski jskulski - 1 year ago 105
Javascript Question

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?

Answer Source

As expected, this seems far too difficult to turn into a readable points-free solution. I did take a simpler subset of it, just to see what I could do, and that itself was ugly enough that I didn't carry it through.

If we started with this function:

var fn = function(list) {
    return R.map(function(y) {
        return {
            y: y
        };
    }, list);
}

... which can clearly be recognized as an inner subproblem of the original, then, I can turn it into this monstrosity:

var fn = R.pipe(R.converge(
    R.zip, 
    R.pipe(R.length, R.repeat('y')), 
    R.identity
), R.map(R.apply(R.createMapEntry)));

(Some intermediate steps are in the REPL)

But considering how this looks in es6, that seems extremely counter-productive:

var fn = R.map(y => ({y});

And that's why I use points-free when it makes sense, but don't try to apply it everywhere.


Update

As of version 0.18, Ramda renamed createMapEntry to objOf made converge a binary function, which means the code above no longer works. Nor does the REPL link, as the REPL has been updated. You can see it now updated in the REPL.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download