我需要通过特定步骤对数组的某些元素进行混洗。
我有这个对象数组:
[
{
"_id": "aze54aze",
"boosted": false
},
{
"_id": "94v2d9e3",
"boosted": false
},
{
"_id": "999f5a8az4",
"boosted": false
},
{
"_id": "e9d29a9g",
"boosted": true
},
{
"_id": "f8f2a9f6a",
"boosted": false
},
{
"_id": "pe55z8a",
"boosted": false
},
{
"_id": "pvazpd97",
"boosted": false
},
{
"_id": "ft8azefze",
"boosted": true
},
]
我希望增强后的对象在数组中随机排列,它们之间有两个对象。为了不将它们全部放在数组的开头,我需要将它们“隐藏”在数组中。
这意味着第一个增强对象将移到第一个位置,然后是两个普通对象,然后是第二个增强对象,然后是其他普通对象。
我可以使用Lodash内置函数来实现吗?
答案 0 :(得分:2)
您可以使用 native ES6
javascript功能(例如filter
,reduce
方法和spread syntax
首先,您应该将boosted
和normal
数组 items 分开。然后创建一个新数组,第一个增强对象将位于第一个位置,然后是两个普通对象,然后是第二个增强对象,依此类推...
在将splice
或remove
array 中的normal
个项目添加到结果数组后,我使用了boosted
方法。 这是为什么?因为最后我需要concat
将其余元素添加到结果中。
var arr = [ { "_id": "aze54aze", "boosted": false }, { "_id": "94v2d9e3", "boosted": false }, { "_id": "999f5a8az4", "boosted": false }, { "_id": "e9d29a9g", "boosted": true }, { "_id": "f8f2a9f6a", "boosted": false }, { "_id": "pe55z8a", "boosted": false }, { "_id": "pvazpd97", "boosted": false }, { "_id": "ft8azefze", "boosted": true }, ]
var boosted = arr.filter(item => item.boosted);
var boosted_copy = boosted.slice();
var normal = arr.filter(item => !item.boosted);
var result = boosted.reduce((res, item, i) => {
res.push(boosted_copy.splice(0, 1)[0], ...normal.splice(0, i * 2 + 2));
return res;
}, []).concat(boosted_copy, normal);
console.log(result);
答案 1 :(得分:1)
使用ES6,您可以使用reduce和spread syntax来实现:
const data = [ { "_id": "aze54aze", "boosted": false }, { "_id": "94v2d9e3", "boosted": false }, { "_id": "999f5a8az4", "boosted": false }, { "_id": "e9d29a9g", "boosted": true }, { "_id": "f8f2a9f6a", "boosted": false }, { "_id": "pe55z8a", "boosted": false }, { "_id": "pvazpd97", "boosted": false }, { "_id": "ft8azefze", "boosted": true }, ]
const shuffleMeSoftly = (d, size) => {
let g = d.reduce((r,c) => (r[c.boosted] = [...r[c.boosted] || [], c],r), {})
return g.false.reduce((r,c,i) => {
let nt = g.true[Math.floor(i/size)]
r = i%size == 0 ? [...r || [], ...(nt ? [nt] : []), c] : [...r || [], c]
return r
}, [])
}
console.log(shuffleMeSoftly(data, 2)) // true every 2 false
console.log(shuffleMeSoftly(data, 3)) // true every 3 false
使用lodash和ES6 spread syntax,您可以:
const data = [ { "_id": "aze54aze", "boosted": false }, { "_id": "94v2d9e3", "boosted": false }, { "_id": "999f5a8az4", "boosted": false }, { "_id": "e9d29a9g", "boosted": true }, { "_id": "f8f2a9f6a", "boosted": false }, { "_id": "pe55z8a", "boosted": false }, { "_id": "pvazpd97", "boosted": false }, { "_id": "ft8azefze", "boosted": true }, ]
const shuffleMeSoftly = (d, size) => {
let grouped = _.groupBy(d, 'boosted')
let chunks = _.chunk(grouped.false, size)
return _.reduce(chunks, (r,c,i) => [...r, ...(grouped.true[i] ? [grouped.true[i]] : []), ...c], [])
}
console.log(shuffleMeSoftly(data, 2)) // true every 2 false
console.log(shuffleMeSoftly(data, 3)) // true every 3 false
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
如果将chunks
放入reduce而不是它自己的变量,则实际上是2行,但出于可读性等原因,我保留了它。