【问题标题】:Immutable JS - converting a collection of Maps to a List不可变 JS - 将地图集合转换为列表
【发布时间】:2021-08-20 10:35:50
【问题描述】:

我正在从事的项目中具有以下结构(使用不可变的 JS):

data :[{name: 'john', surname: 'smith', children: [{name: 'sam'}, {name: 'ben'}]},
       {name: 'jane', surname: 'jones', children: [{name: 'tim'}, {name: 'amy'}]}]

对象通过fromJS()转换为不可变JS。

我需要一个具有以下结构的新对象:

data :[{name: 'john', surname: 'smith', children: ['sam','ben']},
       {name: 'jane', surname: 'jones', children: ['tim','amy']}]

任何指针都非常感谢。

【问题讨论】:

  • 更新不可变集合有什么意义?你不应该创建一个新列表吗?
  • 我应该将其改写为创建一个新的结果对象。

标签: javascript immutable.js


【解决方案1】:

Christian 的纯 JS 答案并不完全适用于 immutable.js 对象,因此这里有一些方法可以使用 immutable.js 的集合 API 来实现。

还有更多选项(例如reduce),请随时查看the docs;方法说明通常附带示例。

const raw = [{name: 'john', surname: 'smith', children: [{name: 'sam'}, {name: 'ben'}]},
       {name: 'jane', surname: 'jones', children: [{name: 'tim'}, {name: 'amy'}]}];

const data = Immutable.fromJS(raw);

function run(name, operation) {
  let result;
  console.time(name);
  for(let i=0; i < 50000; i++){
    result = operation();
  }
  console.timeEnd(name);
  console.log(result1.toJS());
}


run('simple', () => {
  // simply updating objects inside a mapping
  result1 = data.map(
    person => person.update('children',
      kidObjs => kidObjs.map(
        kid => kid.get('name')
      )
    )
  );
});


run('withMutations and setIn', () => {
  // using withMutations and setIn
  result2 = data.withMutations(list => {
    list.forEach((val, idx) => {
      list.setIn(
        [idx, 'children'],
        val.get('children').map(kid => kid.get('name'))
      )
    });
  });
});

run('withMutations and update', () => {
  // slightly faster by using withMutations set/update
  result2 = data.withMutations(list => {
    list.forEach((val, idx) => {
      list.set(idx, val.update('children', kids => kids.map(kid => kid.get('name'))))
    });
  });
});
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/4.0.0-rc.14/immutable.min.js"&gt;&lt;/script&gt;

【讨论】:

    【解决方案2】:

    我会使用 map 和 reduce:

    const data = [{name: 'john', surname: 'smith', children: [{name: 'sam'}, {name: 'ben'}]},
           {name: 'jane', surname: 'jones', children: [{name: 'tim'}, {name: 'amy'}]}];
           
    var result = data.map(person => {
      return { name: person.name, 
               surname: person.surname, 
               children: person.children.reduce((acc, c) => {acc.push(c.name); return acc;}, []) }});
     
      console.log(result)

    【讨论】:

    • 不应该 d.name 等是 d.get('name') 因为它们是不可变的 JS 对象?在我转换为 JS 对象(通过 .toJS())后,我已经发布了结果结构
    • 我不知道 ImmutableJS 的确切语法,但将上面的答案转换为它应该不难。
    【解决方案3】:

    类似的东西应该可以工作

    data.map(d => {d.name, d.surname, children: d.children.map(child => child.name)});

    【讨论】:

    • d.name 等不应该是 d.get('name') 因为它们是不可变的 JS 对象。
    • 你可能是对的,我没有关注图书馆
    猜你喜欢
    • 1970-01-01
    • 2012-01-19
    • 2011-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-29
    • 1970-01-01
    • 2013-12-16
    相关资源
    最近更新 更多