在 ram 库中 - javascript - 数据 refactor/grouping

Ramda lib - javascript - data refactor/grouping

我有一些原始的国家和开始时间数据——列在这样的数据中

我尝试使用的库是 ramda https://jsfiddle.net/0kdcvahw/

  var data = [
    {
      "label": "Argentina",
      "isIncluded": true,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T10:00:00Z'), "ending_time": Date.parse('2020-02-14T15:20:00Z')}
      ]
    },
    {
      "label": "Chile",
      "isIncluded": true,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T10:00:00'), "ending_time": Date.parse('2020-05-20T03:24:00')}
      ]
    },
    {
      "label": "United States of America",
      "isIncluded": true,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T11:00:00Z'), "ending_time": Date.parse('2020-03-20T03:24:00')}
      ]
    }
  ];

我想将列表重新配置为更像这样

var data = [
    {
        label: 'Argentina, Chilie',
        value: 90,
    },
    {
        label: 'United States',
        value: 10,
    }
];

所以基本上 - 有 3 个国家 --- 其中 2 个在同一天和同一开始时间开始,例如10:00。 - 1 在同一天开始但 11:00


代码示例 - 但需要删除最后一个逗号

var data = [
    {
      "label": "Argentina",
      "isIncluded": true,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T10:00:00Z'), "ending_time": Date.parse('2020-02-14T15:20:00Z')}
      ]
    },
    {
      "label": "Chile",
      "isIncluded": false,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T10:00:00'), "ending_time": Date.parse('2020-05-20T03:24:00')}
      ]
    },
    {
      "label": "United States of America",
      "isIncluded": true,
      "times": [
        {"text": "", "starting_time": Date.parse('2020-01-14T11:00:00Z'), "ending_time": Date.parse('2020-03-20T03:24:00')}
      ]
    }
  ];


//console.log("data",data);
const groups = R.groupBy(x => x.times[0].starting_time, data);



const newData = Object.keys(groups).map(key => {
  return {
    label: groups[key].reduce((c, n) => `${c}${n.label}, `, ''),
    value: groups[key].length
  }
})

console.log('newData', newData)

Underscore 按函数分组 here.

它 returns 由您作为组提供的 属性 键控的对象图,值是与提供的键匹配的对象

const groups = groupBy(data, item => item.times[0].starting_time)

console.log('groups', groups)

const newData = Object.keys(groups).map(key => {
  return {
    label: groups[key].reduce((c, n) => `${c}${n.label}, `, '')
  }
})

console.log('newData', newData)

这是一个 Ramda 方法:

const transform = pipe (
  groupBy (path (['times', 0, 'starting_time'])),
  values,
  map (applySpec ({
    label: pipe (pluck ('label'), join (', ')),
    value: length
  }))
)

const data = [{"isIncluded": true, "label": "Argentina", "times": [{"ending_time": 1581693600000, "starting_time": 1578996000000, "text": ""}]}, {"isIncluded": false, "label": "Chile", "times": [{"ending_time": 1589945040000, "starting_time": 1578996000000, "text": ""}]}, {"isIncluded": true, "label": "United States of America", "times": [{"ending_time": 1584674640000, "starting_time": 1578999600000, "text": ""}]}]

console .log (transform (data))
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script>const {pipe, groupBy, path, values, map, applySpec, pluck, join, length} = R</script>

我假设某些日期缺少最后一个 "Z" 只是一个拼写错误。如果有些人应该有它而其他人没有,那么你有一些非常奇怪的数据,并且它与你提供的输出不匹配,除非你碰巧住在那个时区的地方。

在那之后,它是 Ramda 的相当简单的代码。 groupBy 接受一个函数,为您提供项目的规范键。这里我们将 path 的结果传递给它。 path 接受一个字符串或整数数组,并返回一个函数,该函数将 return 输入对象路径处的值,如果任何节点不存在,则为未定义。 groupBy (fn) returns 一个对象,在找到的每个规范键上都有一个数组,输入数组中的项目被划分到这些数组中。

我们对该结果调用 values,这只不过是对 Object.values 的引用;它 return 是一个数组数组。

在每个外部数组上(通过 map)我们调用 applySpec,它将键映射到函数,使用这些键创建一个对象,其值是应用的结果输入值对应的函数。对于 value,我们只是 return 底层数组的 length,对于 label,我们从每个对象中提取 label 条目,然后将它们与", ".

在这里的回答中,我经常展示现代 JS 如何使某些 Ramda 功能不那么引人注目。虽然我可以在这里通过将一些简单的 ES6+ 替代方案组合到 applySpecvalues,对 length 使用简单的 lambda,并将 pipe (pluck ('label'), join (', ') 替换为 arr => arr .map (item => item .label) .join (', ') ].但我不打扰,因为我们仍然需要写一个一次性的等价于 groupBy。虽然这并不困难,但我认为代码会比这长得多。而且我看不到它有任何收获。当然,如果我还没有在我的项目中使用 Ramda,我会这样做,但总的来说,现在是使用 Ramda 简化的好时机。