首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用函数式方法格式化多个日期,使之在文本中看起来很好

使用函数式方法格式化多个日期,使之在文本中看起来很好
EN

Code Review用户
提问于 2021-05-12 20:50:36
回答 1查看 107关注 0票数 1

我有一段解决了非常简单的问题的代码--它形成了两个日期,以便在网页上看起来更好看。看起来是这样的:

代码语言:javascript
复制
function formatDateRange(
  days: { firstDay: string, lastDay: string }
): string {

  let first, last;
  first = dayjs(days.firstDay); //dayjs parses string that formatted like this "YYYY-MM-DD" 
  last = dayjs(days.lastDay);   //and returns a wrapper for Date object
  if (first.isSame(last, "date")) {
    first = first.format("DD MMMM, YYYY")
    last = ""

  } else if (first.isSame(last, "month")) {
    first = first.format("DD") + " ... "
    last = last.format("DD, MMMM YYYY")

  } else if (first.isSame(last, "year")) {
    first = first.format("DD MMM") + " ... "
    last = last.format("DD MMM, YYYY")

  } else {
    first = first.format("DD MMM, YYYY") + " ... "
    last = last.format("DD MMM, YYYY")
  }
  return first + last
}

我决定重构它,我得到了这个:

代码语言:javascript
复制
//adapter that allows to use objects and arrays in function-composition
//EDIT: was called "callable"
function pluckFrom<T extends {}>(obj: T) {
  return (key: keyof T) => obj[key]
}

// a function for function-composition 
// (same as compose from redux but order is reversed)
function pipe(...funcs: Function[]) {
  return funcs.reduce((f1, f2) => (...args: any) => f2(f1(...args)))
}

//provides an interface to apply array of functions to array of data
function apply<A>(maps: Array<(a: A) => any>) {
  return {to: (arr: A[]) => arr.map((item, index) => maps[index](item))}
}

//takes array of dates, wrapped in Dayjs object and returns
//true if they're all the same in terms of unit of time 
function isSame([day1, ...rest]: Dayjs[]) {
  return (unit: UnitType) => rest.every(day => day.isSame(day1, unit))
}

interface DateRange {
  firstDay: string;
  lastDay: string;
}
//EDIT: removed redundant "same_" prefix
const case_to_format_map = {
  "date": ["DD MMMM, YYYY", " "],
  "month": ["DD ...", "DD, MMMM YYYY"],
  "year": ["DD MMM ... ", "DD MMM, YYYY"],
  " ": ["DD MMM, YYYY ... ", "DD MMM, YYYY"]
}

type Case = keyof typeof case_to_format_map

//EDIT: slightly refactored 
function formatDateRange({firstDay, lastDay}: DateRange): string {

  const
    getCase = (days: Dayjs[]) => (
      (["date", "month", "year", " "] as UnitType[])
        .filter(isSame(days))[0]
    ) as Case
    ,
    makeFormatter = (f: string) => (d: Dayjs) => d.format(f)
    ,
    getFormatters = pipe(
      getCase,
      pluckFrom(case_to_format_map),
      formats => formats.map(makeFormatter)
    )
    ,
    days = [firstDay, lastDay].map(dayjs)

  return apply(getFormatters(days)).to(days).join(" ")
}

这是更多的代码,但我喜欢它,因为现在我有了4个额外的实用程序函数,它对我来说更易读。除此之外,我不确定我做得更好还是更糟。所以我有这样的问题:

你能读懂吗?

它是否与功能风格和最佳实践相一致?

我不确定是否需要扩展这段代码,但是如何使它更可扩展呢?

EN

回答 1

Code Review用户

发布于 2021-05-13 00:19:33

我个人更喜欢第一个,但这是非常主观的。从第一次阅读代码的人,我可以浏览第一个版本,并对代码的内容有一个很好的了解。对于第二个版本,我看到了一堆抽象函数,需要更长的时间才能看到代码的实际功能。

虽然第二个版本有一些优点,但我不认为在这种情况下,它是值得的,除非你知道这段代码的未来,而我不知道。我想我想指出的一点是,只有在有充分理由的情况下,你才应该重新格式化你的代码。例如,您希望能够在运行时或从代码库的不同部分调用函数行为的某些部分。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/260674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档