将 Object 中的数组 属性 扩展为多个 Object 填充数组值
Expand Array property in Object to Multiple Objects populated w/ Array value
这个问题的标题很糟糕,但很难用语言表达,下面的例子有望解决问题。
我仍在学习 Ramda 的更高级功能,并且大部分时间都在尝试在 Ramda 中使这种转换更加简洁,但 ES6 版本仍然感觉更具可读性和简短性。
我希望 Ramda 高手可以帮助以更好的方式表达这个功能,使用更少的功能,也许更短。
有没有更好的方法用 Ramda 或纯 JS 来写这个?
谢谢!
更新: 向 objects 添加了一些额外的属性,目的是在 objects.[=15 的新数组中保持这些属性完好无损=]
// 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/ramda@0.25.0/dist/ramda.min.js"></script>
const bundles = [
{ name: 'banana', types: ['esm', 'umd'] },
{ name: 'apple', types: ['umd'] }
];
let newArray = [];
bundles.forEach(bundle => {
bundle.types.map(type => {
newArray.push({ name: bundle.name, type })
});
});
console.log(newArray);
This will output =>
[
{
"name": "banana",
"type": "esm"
},
{
"name": "banana",
"type": "umd"
},
{
"name": "apple",
"type": "umd"
}
]
在 JS 中我会选择:
const bundles = [
{
name: 'banana',
types: ['esm', 'umd']
},
{
name: 'apple',
types: ['umd']
}
];
const expanded = (arr) => {
return arr.reduce((o,n)=>{
let result = n.types.map((t)=>{
return {name:n.name, type:t}
});
o = [...o,...result];
return o;
}, []);
}
这里是 fiddle.
说明:
你想要的是一个对象数组(因此 reduce
来收集结果),这些对象是由 map
在类型上构建的集合构建的。
我对 RamdaJS 一无所知
通过查看文档,使用 R.Reduce and R.map 的 Ramda 转换应该是直接的。
为了获取类型,您可以利用 pluck.
我不擅长 Ramda,但在 JS 我看到了潜力:
const allBundles = bundles.reduce(
(acc, { types, ...attrs}) =>
[...acc, ...types.map((type) => ({...attrs, type }))], []);
const bundles = [
{ name: 'banana', types: ['esm', 'umd'] },
{ name: 'apple', types: ['umd'] },
];
console.log('lamda')
console.log(JSON.stringify(allBundles, null, 2));
<script src="https://cdn.jsdelivr.net/npm/ramda@0.25.0/dist/ramda.min.js"></script>
flaMap
看起来会稍微好一点。
这是使用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/ramda@0.25.0/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));
希望对您有所帮助。
这个问题的标题很糟糕,但很难用语言表达,下面的例子有望解决问题。
我仍在学习 Ramda 的更高级功能,并且大部分时间都在尝试在 Ramda 中使这种转换更加简洁,但 ES6 版本仍然感觉更具可读性和简短性。
我希望 Ramda 高手可以帮助以更好的方式表达这个功能,使用更少的功能,也许更短。
有没有更好的方法用 Ramda 或纯 JS 来写这个?
谢谢!
更新: 向 objects 添加了一些额外的属性,目的是在 objects.[=15 的新数组中保持这些属性完好无损=]
// 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/ramda@0.25.0/dist/ramda.min.js"></script>
const bundles = [
{ name: 'banana', types: ['esm', 'umd'] },
{ name: 'apple', types: ['umd'] }
];
let newArray = [];
bundles.forEach(bundle => {
bundle.types.map(type => {
newArray.push({ name: bundle.name, type })
});
});
console.log(newArray);
This will output =>
[
{
"name": "banana",
"type": "esm"
},
{
"name": "banana",
"type": "umd"
},
{
"name": "apple",
"type": "umd"
}
]
在 JS 中我会选择:
const bundles = [
{
name: 'banana',
types: ['esm', 'umd']
},
{
name: 'apple',
types: ['umd']
}
];
const expanded = (arr) => {
return arr.reduce((o,n)=>{
let result = n.types.map((t)=>{
return {name:n.name, type:t}
});
o = [...o,...result];
return o;
}, []);
}
这里是 fiddle.
说明:
你想要的是一个对象数组(因此 reduce
来收集结果),这些对象是由 map
在类型上构建的集合构建的。
我对 RamdaJS 一无所知
通过查看文档,使用 R.Reduce and R.map 的 Ramda 转换应该是直接的。
为了获取类型,您可以利用 pluck.
我不擅长 Ramda,但在 JS 我看到了潜力:
const allBundles = bundles.reduce(
(acc, { types, ...attrs}) =>
[...acc, ...types.map((type) => ({...attrs, type }))], []);
const bundles = [
{ name: 'banana', types: ['esm', 'umd'] },
{ name: 'apple', types: ['umd'] },
];
console.log('lamda')
console.log(JSON.stringify(allBundles, null, 2));
<script src="https://cdn.jsdelivr.net/npm/ramda@0.25.0/dist/ramda.min.js"></script>
flaMap
看起来会稍微好一点。
这是使用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/ramda@0.25.0/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));
希望对您有所帮助。