【问题标题】:How to add item in every N items of array in Javascript如何在Javascript中的每N项数组中添加项目
【发布时间】:2018-01-24 10:26:52
【问题描述】:

在初始阶段,我有一个对象数组:

[
 { type: 'all' },
 { type: 'all' },
 { type: 'all' },
 { type: 'fruit'},
 { type: 'all' },
 { type: 'all' },
 { type: 'fruit' },
 { type: 'all' },
 { type: 'all' },
 { type: 'fruit' },
 { type: 'fruit' }
]

我要插入:

1) 对象:{type: 'toys'} 在每 5 个类型为 all 的项目中

2) 对象:{type: 'clothes'} 在每 2 个类型为 'fruit' 的项目中

预期结果:

[
 { type: 'all' },
 { type: 'all' },
 { type: 'all' },
 { type: 'fruit'},
 { type: 'all' },
 { type: 'all' },
 { type: 'toys' },
 { type: 'fruit' },
 { type: 'clothes' },
 { type: 'all' },
 { type: 'all' },
 { type: 'fruit' },
 { type: 'fruit' },
 { type: 'clothes' }
]

我该如何实现这个功能?我尝试 forEach 添加项目,但是在推送一个项目后,array_demo 长度发生了变化,很难测量哪个是列表的下一个原始项目。

array_demo.forEach((item, index) => {
  array_demo.push({type: 'demo'});
  console.warn(index);
});

【问题讨论】:

  • 在另一个阵列上做而不是在原地做

标签: javascript arrays add


【解决方案1】:

如果找到正确的出现次数,您可以计算出现次数并插入,然后将新对象添加到数组中。

为了计算和保持逻辑,此方法使用具有所需类型作为键和所有其他值的对象,例如 sizetype 用于插入。

{
    all: {
        count: 0,
        size: 5,
        type: 'toys'
    },
    fruit: {
        count: 0,
        size: 2,
        type: 'clothes'
    }
}

var array = [{ type: 'all' }, { type: 'all' }, { type: 'all' }, { type: 'fruit'}, { type: 'all' }, { type: 'all' }, { type: 'fruit' }, { type: 'all' }, { type: 'all' }, { type: 'fruit' }, { type: 'fruit' }],
    types = { all: { count: 0, size: 5, type: 'toys' }, fruit: { count: 0, size: 2, type: 'clothes' } },
    type,
    i = 0;

while (i < array.length) {
    type = types[array[i].type];
    if (type && ++type.count === type.size) {
        array.splice(++i, 0, { type: type.type });
        type.count = 0;
    }               
    ++i;
}

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    你可以使用reduce来统计all和fruits

    const array_demo = [
     { type: 'all' },
     { type: 'all' },
     { type: 'all' },
     { type: 'fruit'},
     { type: 'all' },
     { type: 'all' },
     { type: 'fruit' },
     { type: 'all' },
     { type: 'all' },
     { type: 'fruit' },
     { type: 'fruit' }
    ]
    
    let all = 0;
    let fruit = 0;
    const newArray = array_demo.reduce((acc, item, index) => {
      if(item.type === 'all') {
         if(all === 4) {
           acc.push(item);
           acc.push({type: 'toys'})
           all = 0;
           return acc;
         } else {
           all++;
         }
      }else if(item.type === 'fruit') {
        if(fruit === 1) {
           acc.push(item);
           acc.push({type: 'clothes'})
           fruit = 0;
           return acc;
         } else {
           fruit++;
         }
        
      }
      acc.push(item);
      return acc;
      
    }, []);
    console.log(newArray);

    【讨论】:

      【解决方案3】:

      一种简单而传统的方法:

      let init = [
       { type: 'all' },
       { type: 'all' },
       { type: 'all' },
       { type: 'fruit'},
       { type: 'all' },
       { type: 'all' },
       { type: 'fruit' },
       { type: 'all' },
       { type: 'all' },
       { type: 'fruit' },
       { type: 'fruit' }
      ]
      
      let last = [];
      let allCounter = 0;
      let fruitCounter = 0;
      
      for (let type of init) {
      	last.push(type);
      
      	if (type.type == 'all' ) {
      		allCounter++;
      		if (allCounter == 5) {
      			last.push({type:'toys'})
      			allCounter = 0;
      		}
      	} else if (type.type == 'fruit') {
      		fruitCounter++;
      		if (fruitCounter == 2) {
      			last.push({type: 'clothes'})
      			fruitCounter = 0;
      		}
      	}
      }
      
      console.warn(last)

      【讨论】:

        【解决方案4】:

        其他解决方案,结果相同

        function insertion(my_array){
            var i=0,
                j=0,
                n=my_array.length,
                k=0;
            while(k<n){
                if(my_array[k].type=='all'){
                    i++;console.log(i);
                }else if(my_array[k].type=='fruit'){
                    j++;console.log(j);
                }
                if(i==5){
                    k++;
                    my_array.splice(k,0,{ type: 'toys' });
                    i = 0;
                    n++;
                }else if(j==2){
                    k++;
                    my_array.splice(k,0,{ type: 'clothes' });
                    j = 0;
                    n++;
                }
                k++;
            }
            return my_array;
        }
        

        【讨论】:

          【解决方案5】:

          var data = 
          [
           { type: 'all' },
           { type: 'all' },
           { type: 'all' },
           { type: 'fruit'},
           { type: 'all' },
           { type: 'all' },
           { type: 'fruit' },
           { type: 'all' },
           { type: 'all' },
           { type: 'fruit' },
           { type: 'fruit' }
          ];
          
          var result = [];
          var allCounter = 0;
          var fruitCounter = 0;
          data.forEach(function(item,index){
            result.push(item);
            if(item.type == "all"){
              allCounter++;
            }
            if(item.type == "fruit"){
              fruitCounter++;
            }
            if(allCounter == 5){
              result.push({"type":"toys"});
              allCounter = 0;
            }
            if(fruitCounter == 2){
              result.push({"type":"clothes"})
              fruitCounter = 0;
            }
          });
          
          console.log(result);

          【讨论】:

            【解决方案6】:

            您可以Array#map 数据,并使用2 个外部计数器(fruitall)来计算每个计数器的出现次数。对于具有其中一种类型的每个对象,递增计数器,并检查它是否是第 2 个水果/第 5 个。如果它与条件匹配,则返回一个包含原始对象和添加对象的新数组。然后在Array#concat 中通过spreading 展平所有子数组。

            注意:该解决方案使用@NinaScholz types object 使其更通用。

            const data = [{"type":"all"},{"type":"all"},{"type":"all"},{"type":"fruit"},{"type":"all"},{"type":"all"},{"type":"fruit"},{"type":"all"},{"type":"all"},{"type":"fruit"},{"type":"fruit"}];
            
            const types = {
                all: { count: 0, size: 5, type: 'toys' },
                fruit: { count: 0, size: 2, type: 'clothes' }
            };
            
            const result = [].concat(...data.map((o) => {
              const to = types[o.type];
            
              return !to || ++to.count % to.size ? o : [o, { type: to.type }];
            }));
            
            console.log(result);

            【讨论】:

              【解决方案7】:

              通过以下方式解决了类似的需求:

              const concatAt = (array, predicate, value) => array.reduce(
                  (c, n, idx) => {
                      const at = typeof predicate === 'function' ? predicate(idx, n, array) : predicate === idx
                      const newValue = typeof value === 'function' ? value(n, idx, array) : value
                      return at ? [...c, n, newValue] : [...c, n]
                  } , [])
              const idOddIndex = n => n % 2
              const isNth = nth => n => n % nth === nth - 1
              const increment = n => n + 1
              
              console.log(concatAt([0, 1, 3, 4, 6], idOddIndex, increment)) // [0, 1, 2, 3, 4, 5, 6]
              concatAt([0, 1, 3, 4, 6], isNth(3), increment) // [0, 1, 3, 4, 4, 6]
              

              我希望它会对某人有所帮助。

              【讨论】:

                猜你喜欢
                • 2018-10-18
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-03-10
                • 2015-11-16
                • 1970-01-01
                相关资源
                最近更新 更多