根据数组的属性和组位对数组进行功能排序

我有这个数组:


const nums = [

 {name: 'a', option: false},

 {name: 'b', option: false},

 {name: 'c', option: false},

 {name: 'd', option: false},

 {name: 'e', option: false},

 {name: 'f', option: true},

 {name: 'g', option: true},

 {name: 'h', option: false},

 {name: 'i', option: true},

 {name: 'j', option: false},

 {name: 'k', option: false},

];

我想重新组织这个数组,以便元素在数组中移动时,具有“false”选项的元素按 4 个元素组分组在一起,但如果有一个元素具有“true”选项,它优先并放在 4 个元素的组之前,除非前面的 4 个元素组是完整的(即其长度等于 4)。


结果将是


const nums = [

 {name: 'a', option: false},

 {name: 'b', option: false},

 {name: 'c', option: false},

 {name: 'd', option: false},

 {name: 'f', option: true},

 {name: 'g', option: true},

 {name: 'i', option: true},

 {name: 'e', option: false},

 {name: 'h', option: false},

 {name: 'j', option: false},

 {name: 'k', option: false},

];

我在命令式风格上取得了成功


let stock = [];

let array2 = [];

for (let i = 0; i < nums.length; i ++){

  if (nums[i].option){

    array2.push(nums[i]);

  }

  else {

    stock.push(nums[i]);

    if(stock.length == 4) {

      array2 = array2.concat(stock);

      stock = [];

    }

  }

}


console.log('array2 is', array2);

到目前为止,太好了,我现在想以一种功能性的方式来做这就是我的方式:


let stock = [];

const actual = nums.map(

 (acc => val => {

   if (val.option){

     acc.push(val);

   }

   else {

     stock.push(val);

     if (stock.length === 4) {

       acc = acc.concat(stock);

       stock = [];

     }

   }

   return acc;

 })([]))


console.log('actual is, ', actual[actual.length-1]);

虽然它有效,但我认为函数式编程风格可以改进。你能帮我改进我的代码吗?


注意:有些人发现这个问题有点不寻常(确实如此)。因此,我将提供更多上下文:


潜在的问题是传统样式类无法解决的 UI 样式问题:我有一个网格容器,其中包含四个网格元素的行(当它们未“打开”时)。


当它被打开时,卡片会占用所有的线,并且后面的元素会被推回。问题是它不漂亮,因为我有一些行可能只包含一个或两个未打开的元素,直到下一行,打开的卡片占用下一行的所有空间。


所以这个想法是把四个未打开的元素一组,储存起来,直到我有一组四个,然后将它们刷新到一条线上。如果我遇到一张打开的卡片,我会先显示这张卡片,然后刷新未打开的元素。


慕尼黑的夜晚无繁华
浏览 115回答 2
2回答

收到一只叮咚

我实际上会采用与您类似的方法,使用 achunk作为临时值来存储不完整的组。const group = (data = [], chunk = [], res = []) => {&nbsp; if (!data.length) {&nbsp; &nbsp; // input is empty,&nbsp; &nbsp; // flush any possible incomplete chunk&nbsp; &nbsp; // and return result&nbsp; &nbsp; return [...res, ...chunk];&nbsp; }&nbsp; const [head, ...tail] = data;&nbsp; const next = (...xs) => group(tail, ...xs);&nbsp;&nbsp;&nbsp; if (head.option) {&nbsp; &nbsp; // head.option is true, so you can&nbsp;&nbsp; &nbsp; // safely put it in tail position&nbsp; &nbsp; return next(chunk, [...res, head]);&nbsp; }&nbsp;&nbsp;&nbsp; if (chunk.length < 4) {&nbsp; &nbsp; // chunk is not-complete, so keep accumulating&nbsp; &nbsp; return next([...chunk, head], res);&nbsp; }&nbsp; // chunk is complete, append it to the rest&nbsp;&nbsp; // and create a new one with the current value&nbsp; return next([head], [...res, ...chunk]);};const data = [&nbsp;{name: 'a', option: false},&nbsp;{name: 'b', option: false},&nbsp;{name: 'c', option: false},&nbsp;{name: 'd', option: false},&nbsp;{name: 'e', option: false},&nbsp;{name: 'f', option: true},&nbsp;{name: 'g', option: true},&nbsp;{name: 'h', option: false},&nbsp;{name: 'i', option: true},&nbsp;{name: 'j', option: false},&nbsp;{name: 'k', option: false},];console.log('result is', group(data));递归在这里是可取的,它们的状态是空输入(基本情况)chunk, (res + head)(chunk + head), reshead, (res + chunk)

慕运维8079593

你可以使用递归。const bubble = (xxs, acc = []) => {&nbsp; &nbsp; if (xxs.length === 0) return acc;&nbsp; &nbsp; if (acc.length === 4) return [...acc, ...bubble(xxs)];&nbsp; &nbsp; const [x, ...xs] = xxs;&nbsp; &nbsp; if (x.option) return [x, ...bubble(xs, acc)];&nbsp; &nbsp; return bubble(xs, [...acc, x]);};const nums = [&nbsp;{name: 'a', option: false},&nbsp;{name: 'b', option: false},&nbsp;{name: 'c', option: false},&nbsp;{name: 'd', option: false},&nbsp;{name: 'e', option: false},&nbsp;{name: 'f', option: true},&nbsp;{name: 'g', option: true},&nbsp;{name: 'h', option: false},&nbsp;{name: 'i', option: true},&nbsp;{name: 'j', option: false},&nbsp;{name: 'k', option: false},];const result = bubble(nums);console.log(result);它效率不高,但很实用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript