为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

我有这个数组: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 样式问题:我有一个网格容器,其中包含四个网格元素的行(当它们未“打开”时)。当它被打开时,卡片会占用所有的线,并且后面的元素会被推回。问题是它不漂亮,因为我有一些行可能只包含一个或两个未打开的元素,直到下一行,打开的卡片占用下一行的所有空间。所以这个想法是把四个未打开的元素一组,储存起来,直到我有一组四个,然后将它们刷新到一条线上。如果我遇到一张打开的卡片,我会先显示这张卡片,然后刷新未打开的元素。
查看完整描述

2 回答

?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

我实际上会采用与您类似的方法,使用 achunk作为临时值来存储不完整的组。


const group = (data = [], chunk = [], res = []) => {

  if (!data.length) {

    // input is empty,

    // flush any possible incomplete chunk

    // and return result

    return [...res, ...chunk];

  }


  const [head, ...tail] = data;

  const next = (...xs) => group(tail, ...xs);

  

  if (head.option) {

    // head.option is true, so you can 

    // safely put it in tail position

    return next(chunk, [...res, head]);

  }

  

  if (chunk.length < 4) {

    // chunk is not-complete, so keep accumulating

    return next([...chunk, head], res);

  }


  // chunk is complete, append it to the rest 

  // and create a new one with the current value

  return next([head], [...res, ...chunk]);

};


const data = [

 {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},

];


console.log('result is', group(data));


递归在这里是可取的,它们的状态是

  1. 空输入(基本情况)

  2. chunk, (res + head)

  3. (chunk + head), res

  4. head, (res + chunk)


查看完整回答
反对 回复 2022-01-07
?
慕运维8079593

TA贡献1876条经验 获得超5个赞

你可以使用递归。


const bubble = (xxs, acc = []) => {

    if (xxs.length === 0) return acc;

    if (acc.length === 4) return [...acc, ...bubble(xxs)];

    const [x, ...xs] = xxs;

    if (x.option) return [x, ...bubble(xs, acc)];

    return bubble(xs, [...acc, x]);

};


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},

];


const result = bubble(nums);


console.log(result);

它效率不高,但很实用。


查看完整回答
反对 回复 2022-01-07
  • 2 回答
  • 0 关注
  • 114 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信