【问题标题】:Add object property value on particular condition with Ramda使用 Ramda 在特定条件下添加对象属性值
【发布时间】:2021-09-20 08:56:31
【问题描述】:

我是 Ramda 的新手,在尝试进行一些对象转换时遇到了一面墙。

我有一个对象数组,必须映射它并转换每个对象。

想要的转换:

  1. 重命名每个对象键
  2. 为每个对象添加新键,基于另一个键(值取决于条件

代码如下:

初始数组:

const items = [
  {
    id: 1,
    name: 'Name 1',
    factors: [
      { id: 11, name: '11', },
      { id: 12, name: '12', },
      { id: 13, name: '13', },
      { id: 14, name: '14', },
      { id: 15, name: '15', },
    ]
  },
  {
    id: 2,
    name: 'Name 2',
    factors: [],
  },
];

想要的输出数组:

const items = [
  {
    key: 1,           // changed property key - already done
    title: 'Name 1',  // changed property key - already done
    factors: [
      { id: 11, name: '11', },
      { id: 12, name: '12', },
      { id: 13, name: '13', },
      { id: 14, name: '14', },
      { id: 15, name: '15', },
    ],
    // add property icon (done)
    // set icon prop based on factors length
    icon: '',        
  },
  {
    key: 2,
    title: 'Name 2',
    // add property icon (done)
    // set icon prop based on factors length
    icon: 'icon'
  },
];
上面列表中的

第一个目标已完成 - 我可以更改每个对象的属性键。 我还可以为每个对象添加一个新键。但我无法设置这个新属性的值基于因素 Array.length

这是当前代码:

const items = [
  {
    id: 1,
    name: 'Name 1',
    factors: [
      { id: 11, name: '11', },
      { id: 12, name: '12', },
      { id: 13, name: '13', },
      { id: 14, name: '14', },
      { id: 15, name: '15', },
    ]
  },
  {
    id: 2,
    name: 'Name 2',
  },
];

const renameKeys = curry((keysMap, obj) =>
  reduce((acc, key) => assoc(keysMap[key] || key, obj[key], acc), {}, keys(obj))
);

const result = map(pipe(
  renameKeys({ id: 'key', name: 'title' }),
  assoc('icon', '---'),  // <= here, set it based on condition - factors.length
), items);

console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"  crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script> const {curry, assoc, map, pipe, reduce, keys} = R </script>

【问题讨论】:

    标签: functional-programming ramda.js


    【解决方案1】:

    Ramda 有 2 个有用的方法来转换对象 - R.evolveR.applySpec。两种方法都接受带有键的对象,以及每个键的转换/创建(取决于方法)函数。

    在这种情况下,您可以使用R.applySpec 生成具有所需键名和值的新对象。

    const { map, applySpec, prop, pipe, length, ifElse, always } = R;
    
    const selectIcon = pipe(prop('factors'), length, ifElse(isNaN, always('icon1'), always('icon2')))
    
    const fn = map(applySpec({
      key: prop('id'),
      title: prop('name'),
      factors: prop('factors'),
      icon: selectIcon
    }));
    
    const items = [{"id":1,"name":"Name 1","factors":[{"id":11,"name":"11"},{"id":12,"name":"12"},{"id":13,"name":"13"},{"id":14,"name":"14"},{"id":15,"name":"15"}]},{"id":2,"name":"Name 2"}];
    
    const result = fn(items);
    
    console.log(result);
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous" referrerpolicy="no-referrer"&gt;&lt;/script&gt;

    转换器函数也可以使用R.applySpec 来更改嵌套值:

    const { map, applySpec, prop, pipe, when, length, ifElse, always } = R;
    
    const selectIcon = pipe(prop('factors'), length, ifElse(isNaN, always('icon1'), always('icon2')))
    
    const keysUpdater = {
      key: prop('id'),
      title: prop('name'),
    };
    
    const factorsTransformer = pipe(prop('factors'), when(length, map(applySpec(keysUpdater))));
    
    const fn = map(applySpec({
      ...keysUpdater,
      factors: factorsTransformer,
      icon: selectIcon
    }));
    
    const items = [{"id":1,"name":"Name 1","factors":[{"id":11,"name":"11"},{"id":12,"name":"12"},{"id":13,"name":"13"},{"id":14,"name":"14"},{"id":15,"name":"15"}]},{"id":2,"name":"Name 2"}];
    
    const result = fn(items);
    
    console.log(result);
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js" integrity="sha512-3sdB9mAxNh2MIo6YkY05uY1qjkywAlDfCf5u1cSotv6k9CZUSyHVf4BJSpTYgla+YHLaHG8LUpqV7MHctlYzlw==" crossorigin="anonymous" referrerpolicy="no-referrer"&gt;&lt;/script&gt;

    【讨论】:

    • 另外,如果我想映射 [factors] 键并更改每个对象键:键 [id] 变为 [key] 键 [name] 变为 [title] 什么是更清洁大大地?我尝试映射 [prop('factors')] 但没有成功。
    • key [name] 变成空字符串?
    • 新键 [title] 与旧 [name] 的值一致,新键 [key] 与 [id] 的值一致。基本上,只需更改键和值以保持不变。
    • 我添加了另一个示例
    • 太棒了!感谢您的帮助 Ori! :-)
    猜你喜欢
    • 2022-11-27
    • 1970-01-01
    • 2015-07-04
    • 1970-01-01
    • 2020-04-11
    • 1970-01-01
    • 1970-01-01
    • 2013-12-08
    • 2021-03-01
    相关资源
    最近更新 更多