1

I have an array with data which I would like to convert into an array with only 5 elements long. For example:

[1,2,3,4,5,6] => [1,2,3,4,5]

or, if the original array has less than 5 elements inside

[1,2,3] => [1,2,3, undefined, undefined]

(I need 'undefined' vals because I'd like to iterate over them later and fill with some default values). So the question is how to do it in Ramda way?

Thanks!!

6
  • Is using ramda mandatory? This can be accomplished in plain javascript as well. Commented Oct 23, 2018 at 12:55
  • do you want to take the same array, or a new one? Commented Oct 23, 2018 at 12:56
  • 1
    Yes. I'm interested how it looks using Ramda. Using plain js is pretty straitforward arr.length = 5; Commented Oct 23, 2018 at 12:57
  • It doesn't matter for me whether it'll be the same array or cloned and modified copy Commented Oct 23, 2018 at 12:59
  • did you try by setting the required value as the length of the array? e.g arr.length = 5 Commented Oct 23, 2018 at 13:01

1 Answer 1

4

You might want to be a little bit wary of thinking about "the Ramda way." Ramda (disclaimer: I'm one of the Ramda authors) is simply a library, a toolkit. It is not meant to dictate anything about how you write your code, only to make it easier to write in a certain manner... when that manner is appropriate.

That said, it's easy enough to write this using Ramda:

const {compose, take, concat, __, repeat} = R

const toFixed = (n, d) => compose(take(n), concat(__, repeat(d, n)))
const take5 = toFixed(5, undefined)

console.log(take5([1, 2, 3, 4, 5, 6])) //=> [1, 2, 3, 4, 5]
console.log(take5([1, 2, 3]))          //=> [1, 2, 3, undefined, undefined]
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>

Note that this offers you the possibility, if it helps, of choosing that default value at fill time. That may or may not be useful to you, but you can just choose undefined if you like.

This is not entirely point-free. Could it be made so? Presumably. But it is readable as is (mostly*), and I would probably not bother going any further.

The big issue, though, is that Ramda here does not offer much of an improvement over what we would write without the library. Here's another version, without Ramda:

const toFixed2 = (n, d) => (xs) => xs.concat(Array(n).fill(d)).slice(0, n)
const brubeck = toFixed2(5, undefined)

console.log(brubeck([1, 2, 3, 4, 5, 6])) //=> [1, 2, 3, 4, 5]
console.log(brubeck([1, 2, 3]))          //=> [1, 2, 3, undefined, undefined]

If find the Ramda version slightly more readable, and it's a little shorter. But it is not a drastic improvement. I would never introduce Ramda to a code-base only for this minor improvement. But if I was already using Ramda, I would choose that version.

Update

The discussion in the comments to this answer mentions another solution, related to one in the question's comments:

const desmond = (arr) => (arr = arr.slice(0), arr.length = 5, arr)

(You could also skip the slice step if you don't mind mutating your original array.)

This of course has a different API than the above, and does not allow you to supply the default value. But there is one other subtle difference.

All solutions get arrays that report length of 5; they have the same JSON.strigify output, they report the same values for each index, but:

3 in take5([1, 2, 3])   //=> true
3 in brubeck([1, 2, 3]) //=> true
3 in desmond([1, 2, 3]) //=> false

So there is a discoverable difference. This last solution changes the length of the array, but does not place anything at the missing indices. The earlier two do so. Given that what we're placing is the value undefined, this may not matter at all, but sometimes such subtleties can bite us.


(*) The placeholder (__) always seems to cause functions to seem less readable to some, and more so to others. If you like, you can replace concat(__, foo) with flip(concat)(foo)

Sign up to request clarification or add additional context in comments.

8 Comments

btw, do you now somthing which works opposite of the comma operator, i mean something like (a, a = '') which returns a (the first instead opd the last expression)?
@NinaScholz: I've never seen such a JS construct. What's the reason for it?
sometimes i like to return a former value of a variable and assign a new value to this variable in a short step.by using comma operator, it returns the last expression. i like to get the firs expression, and example wouls be a temporary array like [a, a+= 2][0], which is a bit strange.
No, I haven't seen anything better than your odd array expression -- which I probably wouldn't use in code meant to be read by others. Obviously this question could be answered with a function using just a comma expression ((arr) => (arr = arr.slice(0), arr.length = 5, arr), or without the slice depending upon your appetite for mutation), but that uses the last expression. I was curious if you had a use for your inverted comma expression for this question, or if it was just a side thought.
it was just a side thought.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.