然后Ramda小组将兄弟姐妹转变为儿童

时间:2017-03-06 01:02:30

标签: javascript functional-programming ramda.js

在ramda.js中,如何按字段对列表进行分组和排序,然后将除了每个组的第一项之外的所有项目移动到该项目的子项中?

例如下面我按名称分组并按日期降序排序:

[{ id: 1, name: 'bob', date: '2007-03-05', count: 15},
 { id: 2, name: 'bob', date: '2007-03-04', count: 32},
 { id: 3, name: 'bob', date: '2007-03-01', count: 27},
 { id: 4, name: 'jack', date: '2007-03-04', count: 3},
 { id: 5, name: 'jack', date: '2007-02-22', count: 5}]

[{ id: 1, name: 'bob', date: '2007-03-05', count: 15,
   children: [{ id: 2, name: 'bob', date: '2007-03-04', count: 32},
   { id: 3, name: 'bob', date: '2007-03-01', count: 27}]
 },
 { id: 4, name: 'jack', date: '2007-03-04', count: 3,
   children: [{ id: 5, name: 'jack', date: '2007-02-22', count: 5}]
 }
 ]

我知道我可以使用R.head获取整个列表的顶部项目,其余部分使用R.tail,然后将其添加为R.merge的孩子,但我不知道如何抓住列表中组的顶部或尾部。

4 个答案:

答案 0 :(得分:5)

另一种方法:

const fn = pipe(
  groupBy(prop('name')),
  values,
  map(lift(assoc('children'))(tail, head))
);

如果要在其中包含排序,可以在values,

之后添加
  map(sort(descend(prop('date')))),

如果这是模糊不清的:map(lift(assoc('children'))(tail, head))您可以用等效的替换它:

  map((group) => assoc('children', tail(group), head(group)))

您可以在 Ramda REPL 上看到这一点。

答案 1 :(得分:3)

你尚未将它们分组,只是按名称命名。要将它们分组为数组,请使用R.groupWith

R.groupWith(R.eqProps("name"))

将数据应用于您的数据后,使用map从每个组中创建一个对象。

答案 2 :(得分:2)

这是获得理想结果的一种方式

const groupByName = groupBy(obj => obj.name);
const sortByDate = sortBy(obj => obj.date);
const grouped = pipe(groupByName, map(sortByDate), values);

reduce( (acc, val) => {
 acc.push(merge(head(val), {children: tail(val)}));
 return acc;
}, [], grouped(data));

Ramda snippet

答案 3 :(得分:2)

可能有更好的方法,但我认为这是一个开始:

function yourAnswer (data) {
  const groupByName = groupBy((person) => person.name)
  return (
    Object.values(groupByName(data))
    .map((g) => g.sort((a, b) => a.id - b.id)) // sort by ascending id
    .map(function(g) { // for each group, sorted by id
      const o = Object.assign(g[0]) // create an object from the minimal id
      o['children'] = g.slice(1) // assign 'children' to be equal the other objects in the group
      return o
  })
)}

let data = [{ id: 1, name: 'bob', date: '2007-03-05', count: 15},
            { id: 2, name: 'bob', date: '2007-03-04', count: 32},
            { id: 3, name: 'bob', date: '2007-03-01', count: 27},
            { id: 4, name: 'jack', date: '2007-03-04', count: 3},
            { id: 5, name: 'jack', date: '2007-02-22', count: 5}]

console.log(yourAnswer(data))

ramda repl处尝试。