不可变 js - 以声明方式从深层嵌套对象中提取值的最佳方式?

Immutable js - best way to extract values from a deeply nested object in a declarative way?

假设我从一个 API 调用中得到一个 json 返回,这个形状一旦被解析:

const foos = {
  foo1: {
    bar1: [{a:1},{a:2},{a:3}],
   bar2: [{a:4},{a:5},{a:6}],
    bar3: [{a:7},{a:8},{a:9}]
  },
  foo2: {
    bar4: [{a:10},{a:11},{a:12}],
    bar5: [{a:13},{a:14},{a:15}]
  }
}

然后,我将其包装在 fromJs() 中以使其不可变。

接下来,我需要遍历该对象以通过这种方式提取值并用它做任何我想做的事:

var obj = {aValue: 0}

Object.keys(foos).forEach( key => {    
  Object.keys(foos[key]).forEach( nestedKey => {
    foos[key][nestedKey].forEach(el => {
      obj.aValue = el.a
      console.log(obj)
    })    
  })
})

在控制台中:

{ aValue: 1 }
{ aValue: 2 }
{ aValue: 3 }
{ aValue: 4 }
{ aValue: 5 }
{ aValue: 6 }
{ aValue: 7 }
{ aValue: 8 }
{ aValue: 9 }
{ aValue: 10 }
{ aValue: 11 }
{ aValue: 12 }
{ aValue: 13 }
{ aValue: 14 }
{ aValue: 15 }

以声明方式使用 Immutable JS 执行此操作的最佳方法是什么?

您可以使用 flatten,它会创建一个新的扁平化集合。

// flatten the first two levels
const foos =  Immutable.fromJS({...});
const flatCollection = foos.flatten(2);
flatCollection.forEach(val => console.log('flat entry', val.get('a')));

如果您只想遍历数据而不是创建集合,使用 Immutable 的 forEach 遍历层可能是更好(也更快)的方法。这也可以与 .reduce

结合使用

const foos = Immutable.fromJS({
  foo1: {
    bar1: [{a:1},{a:2},{a:3}],
    bar2: [{a:4},{a:5},{a:6}],
    bar3: [{a:7},{a:8},{a:9}]
  },
  foo2: {
    bar4: [{a:10},{a:11},{a:12}],
    bar5: [{a:13},{a:14},{a:15}]
  }
});

// go into all immmutable collections and process their values
function deepLoop(value, key) {
  if (Immutable.isCollection(value)) {
    value.forEach(deepLoop);
  } else {
    console.log('primitive entry', key, value);
  }
}
foos.forEach(deepLoop);

// go into all maps and process the lists differently
function deepMap(value, key, context) {
  if (Immutable.Map.isMap(value)) {
    value.forEach(deepMap, key);
  } else {
    value.forEach(val => console.log('list entry', val.get('a')));
  }
}
foos.forEach(deepMap);
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/4.0.0-rc.12/immutable.js"></script>