将嵌套对象推送到数组中的下一个对象 [功能样式]
Pushing nested objects to next object in array [functional style]
我正在尝试从一个看起来像这样的对象中获取
[{current: [1], queue: []}, {current: [2], queue: []}, {current: [3], queue: []}]
对此:
[{current: [], queue: [3]}, {current: [], queue: [1]}, {current: [], queue: [2]}]
基本上,我想将 "current" 中的项目推送到下一个项目的队列。
我想使用 lodash 或 ramda.js 以函数式风格执行此操作。我对函数式编程很陌生,我 运行 对如何做到这一点感到困惑,尤其是处理 arr[2] -> arr[0] 的情况。我考虑过使用 reduce,但我不确定这是否是解决问题的最佳方法。
一个简单的方法是制作深拷贝并将最后一项移动到该副本的第一个位置。
然后迭代原始以将每个队列更新为重新排列的副本中的匹配索引
var data = [{current: [1], queue: []}, {current: [2], queue: []}, {current: [3], queue: []}],
// make a copy of array
copy = JSON.parse(JSON.stringify(data));
// move last to first in copy
copy.unshift(copy.pop());
data.forEach((el,i)=> {
el.queue = copy[i].current;
el.current.length = 0;
});
console.log(data)
您可以使用 lodash#map
来实现。
var result = array.map(function(value, index) {
// get previous array value
var prev = array[(index - 1 + array.length) % array.length];
return Object.assign(
{}, // Makes sure that we don't mutate the original array
value, // retain properties that are not `current` and `queue`
{ current: prev.queue, queue: prev.current } // override
);
});
var array = [{
current: [1],
queue: []
}, {
current: [2],
queue: []
}, {
current: [3],
queue: []
}];
var result = array.map(function(value, index) {
// get previous array value
var prev = array[(index - 1 + array.length) % array.length];
return Object.assign(
{}, // Makes sure that we don't mutate the original array
value, // retain properties that are not `current` and `queue`
{ current: prev.queue, queue: prev.current } // override
);
});
console.log(result);
.as-console-wrapper { min-height: 100%; top: 0; }
一个有趣的 ramda 解决方案:
- 创建一个新数组,在最后一项之前添加(例如:
[1, 2, 3]
到 [3, 1, 2, 3]
)
- 使用
aperture
创建对(例如:[[3,1], [1,2], [2,3]]
)
- 使用合并功能从一对中创建一个新项目(例如:
[4, 3, 5]
)
mergePair
和 loop
函数可能有不同的写法...我在文档中找不到合适的人选。
const data = [{current: [1], queue: []}, {current: [2], queue: []}, {current: [3], queue: []}];
const mergePair = ([left, right]) =>
({ current: [], queue: concat(right.queue, left.current) })
const loop = arr => prepend(last(arr), arr);
const updateQueue = pipe(
loop,
aperture(2),
map(mergePair)
)
updateQueue(data);
试一试here
我正在尝试从一个看起来像这样的对象中获取
[{current: [1], queue: []}, {current: [2], queue: []}, {current: [3], queue: []}]
对此:
[{current: [], queue: [3]}, {current: [], queue: [1]}, {current: [], queue: [2]}]
基本上,我想将 "current" 中的项目推送到下一个项目的队列。
我想使用 lodash 或 ramda.js 以函数式风格执行此操作。我对函数式编程很陌生,我 运行 对如何做到这一点感到困惑,尤其是处理 arr[2] -> arr[0] 的情况。我考虑过使用 reduce,但我不确定这是否是解决问题的最佳方法。
一个简单的方法是制作深拷贝并将最后一项移动到该副本的第一个位置。
然后迭代原始以将每个队列更新为重新排列的副本中的匹配索引
var data = [{current: [1], queue: []}, {current: [2], queue: []}, {current: [3], queue: []}],
// make a copy of array
copy = JSON.parse(JSON.stringify(data));
// move last to first in copy
copy.unshift(copy.pop());
data.forEach((el,i)=> {
el.queue = copy[i].current;
el.current.length = 0;
});
console.log(data)
您可以使用 lodash#map
来实现。
var result = array.map(function(value, index) {
// get previous array value
var prev = array[(index - 1 + array.length) % array.length];
return Object.assign(
{}, // Makes sure that we don't mutate the original array
value, // retain properties that are not `current` and `queue`
{ current: prev.queue, queue: prev.current } // override
);
});
var array = [{
current: [1],
queue: []
}, {
current: [2],
queue: []
}, {
current: [3],
queue: []
}];
var result = array.map(function(value, index) {
// get previous array value
var prev = array[(index - 1 + array.length) % array.length];
return Object.assign(
{}, // Makes sure that we don't mutate the original array
value, // retain properties that are not `current` and `queue`
{ current: prev.queue, queue: prev.current } // override
);
});
console.log(result);
.as-console-wrapper { min-height: 100%; top: 0; }
一个有趣的 ramda 解决方案:
- 创建一个新数组,在最后一项之前添加(例如:
[1, 2, 3]
到[3, 1, 2, 3]
) - 使用
aperture
创建对(例如:[[3,1], [1,2], [2,3]]
) - 使用合并功能从一对中创建一个新项目(例如:
[4, 3, 5]
)
mergePair
和 loop
函数可能有不同的写法...我在文档中找不到合适的人选。
const data = [{current: [1], queue: []}, {current: [2], queue: []}, {current: [3], queue: []}];
const mergePair = ([left, right]) =>
({ current: [], queue: concat(right.queue, left.current) })
const loop = arr => prepend(last(arr), arr);
const updateQueue = pipe(
loop,
aperture(2),
map(mergePair)
)
updateQueue(data);
试一试here