Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid double concat in Ramda

My question is simple. I started with Ramda recently, and I like it, for it is pure functional. I have a little issue with concat function, as it only accepts two lists as arguments. So, if I need to concat three lists or more, I have to chain functions like this: concat(list1, concat(list2, concat(list3, list4))) (for a four lists concatenation). Is there any better way to do this, that I don't know? Thanks.

like image 615
Mateus Felipe Avatar asked Dec 19 '15 22:12

Mateus Felipe


People also ask

Is ramda better than Lodash?

Ramda is generally a better approach for functional programming as it was designed for this and has a community established in this sense. Lodash is generally better otherwise when needing specific functions (esp. debounce ).

Should I use ramda?

Yep. Ramda is an excellent library for getting started on thinking functionally with JavaScript. Ramda provides a great toolbox with a lot of useful functionality and decent documentation.

What is compose in ramda?

compose FunctionPerforms right-to-left function composition. The rightmost function may have any arity; the remaining functions must be unary.

What is Ramda in JavaScript?

Ramda is a practical functional library for JavaScript programmers. The library focuses on immutability and side-effect free functions. Ramda functions are also automatically curried, which allows to build up new functions from old ones simply by not supplying the final parameters.


5 Answers

If you want to concatenate a list of lists, you can reduce the list using R.concat with an empty list as the initial value.

const concatAll = R.reduce(R.concat, []);
concatAll([[1, 2], [3, 4], [5, 6]]);

Or just pass the lists directly to R.reduce.

R.reduce(R.concat, [], [[1, 2], [3, 4], [5, 6]]);

If you want to create a new variadic function that takes each list as a separate argument, then you can wrap the function with R.unapply.

const concatAll_ = R.unapply(R.reduce(R.concat, []));
concatAll_([1, 2], [3, 4], [5, 6]);

Ramda also has an R.unnest function, which when given a list of lists will concatenate them together.

R.unnest([[1, 2], [3, 4], [5, 6]]);
like image 144
Scott Christopher Avatar answered Oct 23 '22 05:10

Scott Christopher


You can use flatten method this way:

R.flatten([list1, list2, list3, list4, ])

Technically you pass a single array, which contains all your lists. Then you just flatten them all into a single array.

Do NOT use this method if some of your lists might contain list themselves - they'll be flattened as well.

like image 40
tlumko Avatar answered Oct 11 '22 14:10

tlumko


I haven't used the Ramda library, but you appears to be using this in node.js from the documentation I've read in the link you posted. In that case, you can use the arguments variable in a function in node.js to write your own concat function that takes n lists as input. The arguments variable is essentially an array of the arguments inputted into the function.

function myConcat () {
  for (var i = 1; i < arguments.length; i++) {
    concat(arguments[0], arguments[i]);
  }
  return arguments[0];
};

In this case however, you would probably have to call it like:

list1 = myConcat(list1, list2, list3, list4);
like image 1
hargasinski Avatar answered Oct 23 '22 03:10

hargasinski


Depending on exactly what you are concatenating and your environment (ES2015 required), you could do:

 const newList = [...list1, ...list2, ...list3];

Otherwise, you are stuck with multiple calls to concat, though you could make it a little cleaner with compose:

 const newList = compose(concat(list1), concat(list2), concat(list4))(list3);

really though you want to map or better, reduce:

 const newList = reduce((acc, x) => concat(acc, x), [list3], [list4, list2, list1]);

or that inner reduce function could look like:

 (acc, x) => [...acc, ...x]
like image 1
low_ghost Avatar answered Oct 23 '22 05:10

low_ghost


Using R.unnest with R.unapply allows you to call your function as a variadic:

const unnestAll = R.unapply(R.unnest)
unnestAll([1, 2], [3, 4], [5, 6, 7]) //=> [1, 2, 3, 4, 5, 6, 7]

A slight variation on Scott Cristopher's answer

See Example in repl

like image 1
robstarbuck Avatar answered Oct 23 '22 03:10

robstarbuck