使用Immutable的List
和Map
集合考虑以下example:
const Map = Immutable.Map;
const List = Immutable.List;
const origin = List([Map({name: 'element1', groupKey: Map({id1: 'foo', id2: 'bar'})}), Map({name: 'element2', groupKey: Map({id3: 'foo'})})]);
console.log("Origin:", String(origin));
const grouped = origin.groupBy( el => el.get('groupKey'));
console.log("Grouped:", String(grouped));
console.log("Expected", "OrderedMap { 'id1': List [ Map { 'name': 'element1', 'groupKey': Map { 'id1': 'foo', 'id2': 'bar' } } ], 'id2': List [ Map { 'name': 'element1', 'groupKey': Map { 'id1': 'foo', 'id2': 'bar' } } ], 'id3': List [ Map { 'name': 'element2', 'groupKey': Map { 'id3': 'foo' } } ] }");
基本上,我要寻找的是一种将origin
中的包含的地图按groupKey
分组的方式,其中每个id(id1
,{{1} },id2
)指向beloging地图:
id3
我不知道如何分割从{
id1: [{'name': 'element1', ...}],
id2: [{'name': 'element1', ...}],
id3: [{'name': 'element2', ...}],
}
返回的结果键(在本例中为Maps)。我尝试使用API提供的mapping functions,但似乎无法根据需要使用它们来更改基数。
最干净的方法是什么?
答案 0 :(得分:0)
el.get('groupKey')
的值是唯一的映射。因此,每个元素都在自己的组中。
groupBy
函数无法通过多个键进行分组,每个元素都将在一个分组中。
const origin = List([
Map({name: 'element1', groupKey: 'banana'}),
Map({name: 'element2', groupKey: 'rocket'}),
Map({name: 'element3', groupKey: 'rocket'}),
Map({name: 'element4', groupKey: 'rocket'}),
]);
const groupedMap = origin.groupBy( el => el.get('groupKey'));
// results in:
// "OrderedMap { 'banana': List [ Map { 'name': 'element1', 'groupKey': 'banana' } ], 'rocket': List [ Map { 'name': 'element2', 'groupKey': 'rocket' }, Map { 'name': 'element3', 'groupKey': 'rocket' }, Map { 'name': 'element4', 'groupKey': 'rocket' } ] }"
如果要按示例对多个值进行分组,则需要编写自己的分组函数。列表可能对分组键更有意义,但让我们继续以下示例:
const Map = Immutable.Map;
const List = Immutable.List;
const OrderedMap = Immutable.OrderedMap;
const origin = List([
Map({name: 'element1', groupKey: Map({id1: 'foo', id2: 'bar'})}),
Map({name: 'element2', groupKey: Map({id3: 'foo'})}),
Map({name: 'element3', groupKey: Map({id99: 'bar'})}),
Map({name: 'element4'}),
]);
function groupByMap(map, mapKey) {
const groups = {};
let keyMap;
map.forEach(elem => {
keyMap = elem.get(mapKey);
if (Immutable.isCollection(keyMap)) {
keyMap.valueSeq().forEach(k => {
if (!groups[k]) {
groups[k] = [elem];
} else {
groups[k].push(elem);
}
});
} else if(groups['lost+found']){
groups['lost+found'].push(elem);
} else {
groups['lost+found'] = elem;
}
});
return Immutable.fromJS(groups);
}
const grouped = groupByMap(origin, 'groupKey');
console.log("Grouped:", String(grouped));
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/4.0.0-rc.9/immutable.js"></script>