javascript - Immutable.js 拆分 Map 类型的键

标签 javascript immutable.js

考虑以下 example使用 Immutable 的 ListMap 集合:

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' } } ] }");

基本上,我正在寻找的是一种通过groupKey对来自origin的包含 map 进行分组的方法,其中每个id(id1 , id2, id3) 指向以下映射:

{
 id1: [{'name': 'element1', ...}],
 id2: [{'name': 'element1', ...}],
 id3: [{'name': 'element2', ...}],
} 

我不知道如何拆分从 groupBy 返回的结果键(在本例中是 map )。我尝试使用 mapping functions由 API 提供,但它们似乎不能用于根据需要更改基数。

实现这一目标的最简洁方法是什么?

最佳答案

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>

关于javascript - Immutable.js 拆分 Map 类型的键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50938371/

相关文章:

javascript - 在 Redux 中切换到 Immutable.js。对性能有何影响以及对组件语法有何影响?

javascript - 大量同时连接

javascript - Angular 级联下拉菜单

javascript - 如何按值传递到 javascript Promise

javascript - Immutable.js 数据结构的自定义相等语义

javascript - 不可变数据结构有哪些常见用途?

javascript - 使用 HOC 加载程序时的重新渲染问题

javascript - 阻塞 CSS 资源

javascript - 首次使用后禁用 .click 事件

javascript - ImmutableJS 记录合并