简体   繁体   中英

How do I retain the key name in the result using a lodash .map()?

log(_.map(businessOpenSlots, weekday => {
        return _.spread(_.union)(_.map(weekday, slot => {
           return this.getTimeStops(slot.open, slot.close);
        }))
    } ))

This is code above is printing below. However, instead of 0..4, I want to key to be weekday.

Not sure how to best achieve this.

在此处输入图片说明

the businessOpenSlots data is below

{
   "friday":[
      {
         "open":"0900",
         "close":"1700"
      }
   ]"monday":[
      {
         "open":"0800",
         "close":"1530"
      },
      {
         "open":"1730",
         "close":"1930"
      }
   ]"thursday":[
      {
         "open":"0900",
         "close":"1700"
      }
   ]"tuesday":[
      {
         "open":"24hrs",
         "close":"24hrs"
      }
   ]"wednesday":[
      {
         "open":"0900",
         "close":"1700"
      }
   ]
}

Found the solution myself and posting it here for the community.

I just had to use _.mapValues() from Lodash.

let availableSlots = _.mapValues(businessOpenSlots, function(slots, weekday) {
       return _.spread(_.union)(_.map(slots, slot => {
          return vm.getTimeStops(slot.open, slot.close);
       }))
    });
log(availableSlots)

It returns the following, just as I wanted.

在此处输入图片说明

You can also do this relatively simply with vanilla JS. Here's one version:

 const hoursToTimeStops = businessOpenSlots => Object .fromEntries ( Object .entries (businessOpenSlots) .map (([d, h]) => [d, h .flatMap (vm .getTimeStops)]) ) const businessOpenSlots = {monday: [{open: "0800", close: "1530"}, {open: "1730", close: "1930"}], tuesday: [{open: "24hrs", close: "24hrs"}], wednesday: [{open: "0900", close: "1700"}], thursday: [{open: "0900", close: "1700"}], friday: [{open: "0900", close: "1700"}]} console .log (hoursToTimeStops (businessOpenSlots))
 .as-console-wrapper {max-height: 100% !important; top: 0}
 <script> // Dummy implementation for `vm`. const every15mins = (sh, sm, eh, em) => sh * 60 + sm > eh * 60 + em ? [] : [`${String(sh).padStart(2, '0')}:${String(sm).padStart(2, '0')}`, ...every15mins(sh + (sm >= 45 ? 1 : 0), (sm + 15) % 60, eh, em)] const vm = {getTimeStops: ({open, close}) => open === '24hrs' ? ["00:00"] : every15mins(Number(open.slice(0, 2)), Number(open.slice(2, 4)), Number(close.slice(0, 2)), Number(close.slice(2, 4)))} </script>

The process of calling entries , map ping the results, then calling fromEntries is nicely encapsulated by lodash's mapValues (or Ramda's map .) But the remainder of this seems simpler than your lodash version.

However, I believe you should be able to simplify that version quite a bit. I'm much more familiar with Ramda (disclaimer: I'm one of its authors), and I know that in Ramda, we could simply write :

const hoursToTimeStops = map (chain (vm.getTimeStops))

and I'm guessing you could get something similar using lodash's mapValues in place of map and its flatMap in place of chain . (It probably wouldn't be quite as elegant unless you used Lodash FP, but it wouldn't be that far off.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM