javascriptramda.js

How to return value by id and not index in ramda?


So I have an array of objects with weekdays, it looks like this:

const weekDays = [
      {
        id: 1,
        name: 'monday'
      },
      {
        id: 2,
        name: 'tuesday'
      },
      {
        id: 3,
        name: 'wednesday'
      },
      {
        id: 4,
        name: 'thursday'
      },
      {
        id: 5,
        name: 'friday'
      },
      {
        id: 6,
        name: 'saturday'
      },
      {
        id: 7,
        name: 'sunday'
      }
    ]

And I have a function for formatting a day, it is used for displaying days in select component, it looks like this:

export const formatDay = flip(nth)(['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'])

So this function should return a day name by its id, for example if we pass 1 it should return monday etc., though currently it returns days by their index, so if we pass 1 it returns tuesday, though flip should've dealt with that problem


Solution

  • flip function in your code is not handling the zero-based index of the array properly. The nth function expects a zero-based index, but you are passing the id which starts from 1. You will need to adjust the input to the nth function by subtracting 1 from the input value.

     export const formatDay = (id) => {
          const days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
          return nth(subtract(id, 1))(days);
        };
    

    const weekDays = [
      {id: 1,name: 'monday'},
      {id: 2,name: 'tuesday'},
      {id: 3,name: 'wednesday'},
      {id: 4,name: 'thursday'},
      {id: 5,name: 'friday'},
      {id: 6,name: 'saturday'},
      {id: 7,name: 'sunday'},
    ];
    const formatDay = (id) => {
      const days = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'];
      return R.nth(R.subtract(id, 1), days);
    };
    
    console.log(formatDay(1)); // Output: "monday"
    console.log(formatDay(2)); // Output: "tuesday"
    console.log(formatDay(3)); // Output: "wednesday"
    <script src="https://cdn.jsdelivr.net/npm/ramda@0.29.1/dist/ramda.min.js"></script>


    Alternative way:

    Leveraging Composition principles:

    const formatDay = R.compose(
      R.prop('name'),
      R.flip(R.nth)(weekDays),
      R.dec
    );
    

    <script type="module">
    import * as R from "https://esm.sh/ramda@0.27.2";
    const weekDays = [
      {id: 1,name: 'monday'},
      {id: 2,name: 'tuesday'},
      {id: 3,name: 'wednesday'},
      {id: 4,name: 'thursday'},
      {id: 5,name: 'friday'},
      {id: 6,name: 'saturday'},
      {id: 7,name: 'sunday'},
    ];
    const formatDay = R.compose(
      R.prop('name'),
      R.flip(R.nth)(weekDays),
      R.dec
    );
    console.log(formatDay(1)); // Output: "monday"
    console.log(formatDay(2)); // Output: "tuesday"
    console.log(formatDay(3)); // Output: "wednesday"
    </script>