Underscore.js组有两个级别

时间:2017-11-24 12:44:47

标签: javascript underscore.js

我似乎无法通过datefoo分组来正确说出这一点:

// Using date as numbers for clear example
// date key should be grouped into a key
// Under that key (date), I should see another key of "foo"

let list = [
  { date: "1", foo: "me", result: "meFoo"},
  { date: "1", foo: "me2", result: "meYou"},
  { date: "1", foo: "me3", result: "meHe"},
  { date: "2", foo: "me", result: "meHim"},
  { date: "2", foo: "me2", result: "meHim"}
]

let grouped = _.groupBy(list, "date") // keys ie 1, 2

// I need another key under the date key, possible?
let grouped = _.groupBy(list, "date", (val) => _.groupBy(val), "foo") // result not expected

我在这里变得有点复杂,所以我使用下划线来减轻复杂性。这可能吗?

然后我会做类似的事情,我可以使用_.pluck

Object.keys(grouped).map( dateKey => Object.keys(grouped[dateKey]).map(fooKey => console.log( grouped[dateKey][fookey][0] )) )

在最高级别上看起来真的错了。

预期结果如下:

DATE // key
 |
 |___ FOO // key
       |
       |__ array foo objects

4 个答案:

答案 0 :(得分:4)

功能性(使用reduce):

list.reduce((acc, item) => ({
    ...acc,
    [item.date]: {
        ...(acc[item.date] || {}),
        [item.foo]: (acc[item.foo] || []).concat(item)
    }
}), {})

程序:

let grouped = {}

list.forEach((item) => {
    // Create an empty object if this key has not already been set:
    grouped[item.date] = grouped[item.date] || {}

    // Create an empty list if this key has not already been set:
    grouped[item.date][item.foo] = grouped[item.date][item.foo] || []

    // Push the item to our group:
    grouped[item.date][item.foo].push(item)
})
在python中,这将是:
from collections import defaultdict

_list = [
    {"date":"1","foo":"me","result":"meFoo"},
    {"date":"1","foo":"me2","result":"meYou"},
    {"date":"1","foo":"me3","result":"meHe"},
    {"date":"2","foo":"me","result":"meHim"},
    {"date":"2","foo":"me2","result":"meHim"}
]

grouped = defaultdict(lambda: defaultdict(list))

for item in _list:
    grouped[item['date']][item['foo']].append(item)

答案 1 :(得分:2)

这将为您提供所需的数组。

_.map(_.groupBy(list, 'date'), (value, key) => ({[key]: _.groupBy(value, 'foo')}))

我希望你想要这样的结果:



var list = [{ date: "1", foo: "me", result: "meFoo" }, { date: "1", foo: "me2", result: "meYou" }, { date: "1", foo: "me3", result: "meHe" }, { date: "2", foo: "me", result: "meHim" }, { date: "2", foo: "me2", result: "meHim" }],
    grouped = _.map(_.groupBy(list, 'date'), (value, key) => ({[key]: _.groupBy(value, 'foo')}));

console.log(grouped);

.as-console-wrapper { max-height: 100% !important; top: 0; }

<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
&#13;
&#13;
&#13;

答案 2 :(得分:1)

你快到了。对于第二级分组,您需要映射第一个分组的值:

let result = _.chain(list)
    .groupBy('date')
    .mapObject( grp => _.groupBy(grp, 'foo'))
    .value();

答案 3 :(得分:0)

以下是使用import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'hasString' }) export class HasString implements PipeTransform { transform(value: any): any { let test = value + "1234"; return test; } } 合成实现此目的的另一种方法。我为此使用了Ramda库。首先,通过日期对其进行分组,然后通过foo对其进行分组。另外,请注意我没有找到任何用于迭代对象键的curried函数,这就是我自己添加它的原因。

function
let list = [
  { date: "1", foo: "me", result: "meFoo"},
  { date: "1", foo: "me2", result: "meYou"},
  { date: "1", foo: "me3", result: "meHe"},
  { date: "2", foo: "me", result: "meHim"},
  { date: "2", foo: "me2", result: "meHim"},
  { date: "2", foo: "me2", result: "meHimAnother"}
]

function iterKeys(fn) {
  return function(obj) {
    for (var key in obj) {
      obj[key] = fn(obj[key])
    }
    return obj;
  }
}

var group = R.compose(iterKeys(R.groupBy(R.prop('foo'))), R.groupBy(R.prop('date')))
console.log(group(list));