简体   繁体   中英

Flatten assorted array using ramda

I have the following data structure which contains Date objects, some of which are nested inside objects:

[
  new Date("2018-11-20T09:00:00.000Z"),
  new Date("2018-11-19T09:00:00.000Z"),
  {
    "before": new Date("2018-12-14T00:00:00.000Z")
  }
]

Using ramda, I'd like to flatten it so that it becomes:

[
  new Date("2018-11-20T09:00:00.000Z"),
  new Date("2018-11-19T09:00:00.000Z"),
  new Date("2018-12-14T00:00:00.000Z")
]

I've tried using a combination of map , values , unnest and flatten but with no luck. I would ideally like this to work so that it would flatten regardless of the nested object and key names.

Use R.when with R.has and R.prop to extract the value from objects that has the property inside a map.

 const { pipe, map, when, has, prop } = R; const extractOrVal = (p) => map(when(has(p), prop(p))); const extractOrValBefore = extractOrVal('before'); const data = [ new Date("2018-11-20T09:00:00.000Z"), new Date("2018-11-19T09:00:00.000Z"), { "before": new Date("2018-11-14T00:00:00.000Z") } ]; console.log(extractOrValBefore(data)); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script> 

If there can be multiple keys, or you don't know the name of the keys, you can use R.values. This extracts all values from objects, that are not Date:

 const { chain, values, unless, is } = R; const extractAndFlatten = chain(unless(is(Date), values)); const data = [ new Date("2018-11-20T09:00:00.000Z"), new Date("2018-11-19T09:00:00.000Z"), { "before": new Date("2018-12-14T00:00:00.000Z") } ]; console.log(extractAndFlatten(data)); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script> 

And another suggestion by Scott Christopher to extract unknown/multiple props, and flattening the results:

 const { chain, ifElse, is, of, values } = R; const extractAndFlatten = chain(ifElse(is(Date), of, values)); const data = [ new Date("2018-11-20T09:00:00.000Z"), new Date("2018-11-19T09:00:00.000Z"), { "before": new Date("2018-12-14T00:00:00.000Z") } ]; console.log(extractAndFlatten(data)); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script> 

In case you want plain Javascript solution.

Assumption - Objects are nested to 1 level as seen in OP

 var arr = [ "2018-11-20T09:00:00.000Z", "2018-11-19T09:00:00.000Z", { "before": "2018-11-14T00:00:00.000Z" } ] var result = arr.map(d => typeof d == "object" ? Object.values(d) : d) console.log(result.flat()) 

https://ramdajs.com/docs/#map

Here's a repl , and the code :

let arr = [
"2018-11-20T09:00:00.000Z",
"2018-11-19T09:00:00.000Z",
{
  "before": "2018-11-14T00:00:00.000Z"
}
];

R.map((item) => item.before || item, arr);

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