gosseti
gosseti

Reputation: 975

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.

Upvotes: 1

Views: 1969

Answers (3)

Ori Drori
Ori Drori

Reputation: 191986

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>

Upvotes: 6

zfrisch
zfrisch

Reputation: 8660

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);

Upvotes: 1

Nitish Narang
Nitish Narang

Reputation: 4184

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())

Upvotes: 0

Related Questions