【问题标题】:Flatten assorted array using ramda使用 ramda 展平各种数组
【发布时间】:2019-04-16 16:17:08
【问题描述】:

我有以下数据结构,其中包含Date 对象,其中一些嵌套在对象中:

[
  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")
  }
]

使用 ramda,我想将其展平,使其变为:

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

我尝试使用 mapvaluesunnestflatten 的组合,但没有成功。理想情况下,我希望它能够工作,以便无论嵌套对象和键名如何,它都会变平。

【问题讨论】:

  • 对象是否包含除时间戳之外的其他信息?
  • @BryanDowning 他们没有,不。

标签: javascript arrays functional-programming ramda.js


【解决方案1】:

将 R.when 与 R.has 和 R.prop 结合使用,从地图内具有该属性的对象中提取值。

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>

如果可以有多个key,或者你不知道key的名字,你可以使用R.values。这会从对象中提取所有不是日期的值:

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>

另一个suggestion by Scott Christopher 用于提取未知/多个道具,并将结果展平:

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>

【讨论】:

  • 我已经在答案中包含了可运行的 sn-ps,并且两者都可以工作。我不知道为什么你会得到不同的结果。
  • 现在仔细检查一下,看看我的情况。
  • 会不会在我的控制台中它们是Date 对象?将它们复制到此处时,它们显示为字符串。
  • 这似乎合乎逻辑,因为日期是对象,没有before 属性。
  • 不错的答案。次要的建议是,第二个示例中的 when(complement(f)) 也可以表示为 unless(f)。第二个示例的另一个选项是chain(ifElse(is(Date), of, values))
【解决方案2】:

如果您想要纯 Javascript 解决方案。

假设 - 对象嵌套在 OP 中的 1 级

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

【讨论】:

    【解决方案3】:

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

    这是repl,代码:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-26
      • 2014-04-29
      • 1970-01-01
      • 2018-03-13
      • 2013-05-17
      • 1970-01-01
      相关资源
      最近更新 更多