Перемешать некоторые элементы массива с определенным шагом - PullRequest
0 голосов
/ 23 октября 2018

Мне нужно перемешать некоторые элементы массива с определенным шагом.

У меня есть этот массив объектов:

[
  {
    "_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?

Ответы [ 2 ]

0 голосов
/ 23 октября 2018

С ES6 вы можете добиться этого, используя уменьшить и синтаксис распространения :

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 синтаксис распространения вы можете:

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>

Используя groupBy / chunk и затем уменьшите .

Это действительно две строки, если вы добавляете chunks к редуктору вместо того, чтобы быть его собственной переменной, но я оставил его для удобства чтения и т. Д.

0 голосов
/ 23 октября 2018

Вы можете сделать это, используя нативные ES6 функции JavaScript, такие как filter, reduce методы и синтаксис распространения

Прежде всего, выследует разделить массив boosted и normal items .Затем создайте новый массив, в котором первый усиленный объект перейдет на первую позицию, затем два обычных объекта, затем второй усиленный объект и т. Д. *

Я использовал метод splice, чтобы remove элементовиз normal или boosted array после того, как я добавил их в мой массив результатов. Почему это? Потому что в конце мне нужно 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);
...