2017-03-06 9 views
3

ramda.jsでフィールドを使ってリストをグループ化してソートし、各グループの最初の項目を除くすべての項目をその項目の子に移動するにはどうすればよいですか?私は名前でグループ化され、日付の降順でソートしてきたところ以下Ramdaグループは次に兄弟を子に変換します

例:

[{ 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}] 
} 
] 

の中へ

[{ 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}] 

私はR.headで全体のリストの一番上のアイテムをつかむことができることを知っていますR.mergeで子として追加しますが、リスト内のグループの先頭または末尾を取得する方法はわかりません。

答えて

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

+0

これは素晴らしいです –

3

あなたはそれらをまだグループ化しておらず、名前で注文しただけです。配列の配列へのグループに、R.groupWithを使用します。

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

あなたのデータに、各グループからオブジェクトを作成するためにmapを使用することを適用した後。

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

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