我如何总结重复的数组元素

时间:2019-06-28 21:19:32

标签: javascript arrays sum filtering

程序工作正常,除了“ change”数组有很多重复项外,对重复项求和应该很容易,除非它给出了错误的和! 例如:相加3二十应该给60,相反它给80! 我注意到该错误仅在奇数重复时发生! 我不知道的另一件事是,为什么我对重复项求和时“变化”数组会变化?我将更改数组复制到另一个数组,因此如果第二个数组发生任何变化,则不应影响“更改”数组!

程序运行良好,直到我到达需要对重复项求和的部分为止(sumDuplicates()函数本身可以正常工作,但不适用于我的代码)

function checkCashRegister(price, cash, cid) {
  var change = [];
  let difference = cash - price;
  let level = 0;
  let currency = [
    ["PENNY", 0.01],
    ["NICKEL", 0.05],
    ["DIME", 0.1],
    ["QUARTER", 0.25],
    ["ONE", 1],
    ["FIVE", 5],
    ["TEN", 10],
    ["TWENTY", 20],
    ["ONE HUNDRED", 100]
  ]
  //sum all money in register
  let totalFunds = cid.reduce((r, [key, value]) => {
    return r + value
  }, 0)

  //function to match the difference to appropriate currency
  function findLevel(dif) {
    for (let i = currency.length - 1; i >= 0; i--) {
      //our change must be the highest availabe currency
      if (dif >= currency[i][1] && cid[i][1] != 0) {
        //console.log(currency[i])
        return i
      }
    }
  }
  //function to subtract
  function subtractor(dif, lvl) {
    if (cid[lvl][1] != 0) {
      dif = dif.toFixed(2)
      dif = dif - currency[lvl][1]
      cid[lvl][1] -= currency[lvl][1]
      change.push(currency[lvl])
      return dif
    }
  }
  //if no change needed
  if (difference == 0) {
    return {
      status: "CLOSED",
      change: []
    }
  }
  //if we dont have enough money to pay back
  if (totalFunds < difference) {
    return {
      status: "INSUFFICIENT_FUNDS",
      change: []
    }
  }
  //if we need to pay change AND we have enough money
  if (difference > 0 && totalFunds >= difference) {
    while (difference >= 0.01) {
      level = findLevel(difference)
      difference = subtractor(difference, level)
      //console.log(difference)
    }
  }

  //to sum duplicate elements in the "change" array, this is the problem!!!
  function sumDuplicates(arr1) {
    let arr = [...arr1]
    let sums = arr.reduce((sums, item) => {
      let found = sums.find(([key]) => key === item[0]);
      //console.log(found)
      if (found)
        found[1] += item[1];
      else
        sums.push(item);
      // console.log(item)
      return sums;
    }, []);
    return sums;
  }
  let sums = sumDuplicates(change)
  console.log(sums);
  return {
    status: "OPEN",
    change: sums
  };
}

checkCashRegister(3.26, 100, [
  ["PENNY", 1.01],
  ["NICKEL", 2.05],
  ["DIME", 3.1],
  ["QUARTER", 4.25],
  ["ONE", 90],
  ["FIVE", 55],
  ["TEN", 20],
  ["TWENTY", 60],
  ["ONE HUNDRED", 100]
]);

我希望[[twenties,60]]会得到[[twenties,80]]

2 个答案:

答案 0 :(得分:3)

在将引用推入数组中时需要小心,因为它们不会复制。您需要在几个地方进行操作,并且在void vehicle_recv(void) { uint8_t n = 0; char byte; byte = LINDAT; //Reads and stores the content of the UART data register. if(compass_packet.state == BUFFER_RX_IDLE) { if(byte == '*' || byte == '#') { compass_packet.buffer[0] = byte; compass_packet.index = 1; compass_packet.state = BUFFER_RX_IN_PROG; } } if(compass_packet.state == BUFFER_RX_IN_PROG) { compass_packet.buffer[compass_packet.index] = byte; (compass_packet.index)++; if(byte == 0x0a) { compass_packet.buffer[compass_packet.index] = byte; (compass_packet.index)++; compass_packet.size = compass_packet.index; compass_packet.state = BUFFER_RX_DONE; } } if(compass_packet.state == BUFFER_RX_DONE) { decode_vehicle_command(&compass_packet); compass_packet.state = BUFFER_RX_IDLE; } } uint8_t decode_vehicle_command(struct compass_comm_packet *RX_buffer) { debugChar(debug_str); sendChar(RX_buffer->buffer[0]); sendCRLF(); sendChar(RX_buffer->buffer[1]); sendCRLF(); sendChar(RX_buffer->buffer[2]); sendCRLF(); sendChar(RX_buffer->buffer[3]); sendCRLF(); sendChar(RX_buffer->buffer[4]); sendCRLF(); sendChar(RX_buffer->buffer[5]); sendCRLF(); sendChar(RX_buffer->buffer[6]); sendCRLF(); sendChar(RX_buffer->buffer[7]); sendCRLF(); uint8_t return_value = 0; if(RX_buffer->buffer[0] == '*') { switch(RX_buffer->buffer[1]) { case 'H': strcpy(debug_str, "Heading\r\n"); debugChar(debug_str); break; case 'R': strcpy(debug_str, "Reset\r\n"); debugChar(debug_str); break; case 'S': strcpy(debug_str, "Stop\r\n"); debugChar(debug_str); break; case 'C': strcpy(debug_str, "Calibrate\r\n"); debugChar(debug_str); break; } } 函数中最终修改了原始数组,从而更改了查找表中的值。

sum

一种快速的解决方法是在求和函数中推送副本:

if (found)
     found[1] += item[1]; // <-- now modifying your original currency lookup!
else
     sums.push(item);     // <-- your pushing a ref to your original currency lookup!

(可能是更好的选择)是将副本推入 sums.push([...item]) 数组中:

change

function subtractor(dif, lvl) {
  if (cid[lvl][1] != 0) {
      dif = dif.toFixed(2)
      dif = dif - currency[lvl][1]
      cid[lvl][1] -= currency[lvl][1]
      change.push([...currency[lvl]]) // < push a copy not the original ref
      return dif
   }
 }

答案 1 :(得分:0)

这里是替代的,不太冗长的版本。它返回一个对象,该对象指示您需要退还每张钞票中的多少张。 -从寄存器内容中减去更改。

const subtract = (available, current, value) => {
    let cash = available.find ( ([bill]) => bill === current); 
    if (cash [1] < value) throw new Error ('INSUFFICIENT_FUNDS');
    cash [1] -= value;
}
const computeChange = (price, cash, available) => {
	let sorted = currency.sort ((a,b) => a[1] - b[1]);
	let change = {}
    let sum = 0;
    let highest = sorted.pop ();

    do {
      var [bill, value] = highest;
      if ((sum + value) > price) {
         highest = sorted.pop ()
         continue;
      }
      sum += value;
      subtract (available, bill, value);
      change [highest [0]] = -~change [highest [0]]
    } while (highest && sum <= price)

    return change;
} 
let change = computeChange (3.26, 100, register);
console.log (change, register);
<script>
const register = [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]];
let currency = [
    ["PENNY", 0.01],
    ["NICKEL", 0.05],
    ["DIME", 0.1],
    ["QUARTER", 0.25],
    ["ONE", 1],
    ["FIVE", 5],
    ["TEN", 10],
    ["TWENTY", 20],
    ["ONE HUNDRED", 100]
]
</script>