在JavaScript中,在数组中的插槽中以大致相等的间隔划分和分区

时间:2016-06-17 17:03:01

标签: javascript data-structures

我有一个对象数组,如下所示:

[
  [
    { product: 1, mass: 60 },
    { product: 3, mass: 30 },
    { product: 3, mass: 20 }
  ], [
    { product: 4, mass: 80 },
    { product: 5, mass: 40 }
  ]
]

我希望将此阵列的大小加倍,释放每个插槽旁边的另一个插槽。我想从前一个插槽中取出,并将大致相等的质量分配到这个新创建的插槽中。例如,它看起来如下:

[
  [
    // total mass: 60
    { product: 1, mass: 60 },
  ], [
    // total mass: 50. Newly created.
    { product: 3, mass: 30 },
    { product: 3, mass: 20 }
  ], [
    // total mass: 80
    { product: 4, mass: 80 },
  ], [
    // total mass: 40. Newly created.
    { product: 5, mass: 40 }
  ]
]

如何在JavaScript中完成?

2 个答案:

答案 0 :(得分:0)

如果您不关心生成的订单,则以下代码应该有效。

// helper function to get total mass
function total(arr) {
   return arr.reduce(function(total, item) { return total + item.mass;}, 0);
}

function distribute(cart) {
 // flatten products and sort
 var products = [].concat.apply([], cart)
     .sort(function(a, b){return b.mass - a.mass});
 // calc future avg mass
 var average = total(products)/(2*cart.length);

 return products.reduce(function(acc, product, index) {
   var last; 
   if(!index) { // the very first item
     acc.push([product]);
     return acc;
   }

  last = acc[acc.length - 1]; // take latest cart

  if(total(last) + product.mass > average) { // need next slot
      acc.push([product]);
  }
  else {
     last.push(product); // the last is still capable to get more items
  }
  return acc;
 }, []);
}

答案 1 :(得分:0)

找到了解决方案

export function distribute(
  group,
  field="mass",
  partitionCount=2,
  sorter=(a, b) => a[field] > b[field]
) {
  let index = 0;
  let partition = _.range(partitionCount).map(s => []);
  const copy = Array.from(group);
  while (copy.length !== 0) {
    const item = copy.sort(sorter).shift();
    partition[index%partition.length].push(item);
    index += 1;
  }
  return partition;
}

export function partitionByField(iterable, field="mass", partitionCount=2) {
  return Array.from(iterable).reduce((flattened, group) => {
    return flattened.concat(distribute(group, field, partitionCount));
  }, []);
}