javascriptramda.js

Repeat value infinitely Ramda


For zipping, how can I zip a list with repetitions of a single value?

desired:

R.zip([1, 2, 3])(R.repeat(2)); // [[1, 2], [2, 2], [3, 2]]

Solution

  • You can use R.ap as a combinator of the R.zip function and a function that takes the length, and repeats and item:

    const { ap, zip, pipe, length, repeat } = R
    
    const fn = item => ap(
      zip,
      pipe(length, repeat(item))
    )
    
    const result = fn(2)([1, 2, 3])
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

    This an overkill, but just for the sake of completeness - you can create Infinite lazy arrays in JS using a proxy. Create an array proxy with a get trap. For length return Infinity, and call a cb function to generate an item. In this case I use R.always to create always return 2 for an item:

    const { zip, __, always } = R
    
    const getInfiniteArray = getItem => new Proxy([], {
      get(target, prop, receive) {
        return prop === 'length' 
          ? Infinity
          : getItem(target, prop, receive)
      }
    })
    
    const fn = zip(__, getInfiniteArray(always(2)))
    
    const result = fn()([1, 2, 3])
    
    console.log(result)
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>