javascript - 将对象中的数组属性扩展到填充有数组值的多个对象

标签 javascript functional-programming ramda.js

这个问题的标题很糟糕,但很难用语言表达,希望下面的例子能澄清问题。

我仍在学习 Ramda 的更高级功能,并花了大部分时间试图让 Ramda 中的这种转换更加简洁,但 ES6 版本仍然感觉更具可读性和简短。

我希望 Ramda 高手能够帮助以更好的方式表达这个函数,使用更少的函数,甚至更短。

是否有更好的方法可以用 Ramda 或纯 JS 编写此代码?
谢谢!

更新:向对象添加了一些额外的属性,目的是在新的对象数组中保持这些属性不变。

Link to Ramda REPL

// For every type in bundle.types creates a new bundle obj.

const bundles = [
  {
    name: 'banana',
    input: 'src/banana.js',
    dir: 'dist',
    types: ['esm', 'umd']
  },
  {
    name: 'apple',
    input: 'src/apple.js',
    dir: 'dist',
    types: ['umd']
  }
]

/* =>
[
  {
    name: 'banana',
    input: 'src/banana.js',
    dir: 'dist',
    type: 'esm'
  },
  {
    name: 'banana',
    input: 'src/banana.js',
    dir: 'dist',
    type: 'umd'
  },
  {
    name: 'apple',
    input: 'src/apple.js',
    dir: 'dist',
    type: 'umd'
  }
]
*/

let allBundles = R.chain(R.converge(
  R.pipe(R.xprod, R.map(R.mergeAll)),
  [
    R.pipe(R.dissoc('types'), R.of),
    R.pipe(R.prop('types'), R.map(R.objOf('type')))
  ]
), bundles);

console.log('ramda');
console.log(JSON.stringify(allBundles, null, 2));

allBundles = bundles.reduce((acc, b) => {
  return acc.concat(b.types.map((type) => {
    const bundle = { ...b, type };
    delete bundle.types;
    return bundle;
  }));
}, []);

console.log('lamda')
console.log(JSON.stringify(allBundles, null, 2));
<script src="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c7b5a6aaa3a687f7e9f5f2e9f7" rel="noreferrer noopener nofollow">[email protected]</a>/dist/ramda.min.js"></script>

最佳答案

这是使用 R.chain 的完美场所:

const bundles = [ { name:  "banana"
                  , input: "src/banana.js"
                  , dir:   "dist"
                  , types: ["esm", "umd"]
                  }
                , { name:  "apple"
                  , input: "src/apple.js"
                  , dir:   "dist"
                  , types: ["umd"]
                  }
                ];

const unbundle = ({ types, ...rest }) =>
    types.map(type => ({ ...rest, type }));

const unbundleAll = R.chain(unbundle);

console.log(JSON.stringify(unbundleAll(bundles), null, 2));
<script src="https://cdn.jsdelivr.net/npm/<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="285a49454c496818061a1d0618" rel="noreferrer noopener nofollow">[email protected]</a>/dist/ramda.min.js"></script>

在普通 JS 中也有同样的事情:

const bundles = [ { name:  "banana"
                  , input: "src/banana.js"
                  , dir:   "dist"
                  , types: ["esm", "umd"]
                  }
                , { name:  "apple"
                  , input: "src/apple.js"
                  , dir:   "dist"
                  , types: ["umd"]
                  }
                ];

const unbundle = ({ types, ...rest }) =>
    types.map(type => ({ ...rest, type }));

const concatMap = f => xs => [].concat(...xs.map(f));

const unbundleAll = concatMap(unbundle);

console.log(JSON.stringify(unbundleAll(bundles), null, 2));

希望有帮助。

关于javascript - 将对象中的数组属性扩展到填充有数组值的多个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52018816/

相关文章:

javascript - 淡出与运动相结合

javascript - 函数式 jQuery : Custom Events or Functions?

javascript - lambda : How can I filter data with nested objects?

javascript - Angular 2 在 View /模板中调用函数

javascript - 从获取返回值更新 vuejs 警报组件

javascript - 给定迄今为止的字符串格式

php - 如何在 Codeigniter 函数中对学生分数进行排名

f# - 空隙与单位相反

javascript - 如何访问 Ramda.map 中的迭代数组?

javascript - Ramda - 从数组中查找匹配的对象