JS Sum suite of positive/negative based on range

JS Sum suite of positive / negative based on range

我正在使用 NodeJS (Javascript) 并尝试实现以下结果:

输入:

let input = [{
        value: 'A',
        gap: 1
    }, {
        value: 'B',
        gap: 2
    }, {
        value: 'C',
        gap: 3
    }, {
        value: 'D',
        gap: -2
    }, {
        value: 'E',
        gap: -3
    }, {
        value: 'F',
        gap: 3
    }, {
        value: 'G',
        gap: 0
    }, {
        value: 'H',
        gap: -1
    }, {
        value: 'I',
        gap: 9
    }];

预期结果:

let expectedResult = [{
        value: 'A',
        gap: 6
    }, {
        value: 'D',
        gap: -5
    }, {
        value: 'F',
        gap: 3
    }, {
        value: 'H',
        gap: -1
    }, {
        value: 'I',
        gap: 9
    }];

通过在每次加法中捕获第一个“值”,预期结果将是每组正数/负数的总和。

注意:输出可以是对原始数组的更改或构建新数组。

使用数组映射/归约/排序尝试了不同的方法,但对结果不满意,或者至少无法完全达到我想要的效果。 你能根据你的 POV 提出优化的解决方案吗? 谢谢

首先,为same sign elements创建一个新数组,然后从相反的顺序映射过来,以获得所需的结果。

1)

let input = [
  {
    value: "A",
    gap: 1,
  },
  {
    value: "B",
    gap: 2,
  },
  {
    value: "C",
    gap: 3,
  },
  {
    value: "D",
    gap: -2,
  },
  {
    value: "E",
    gap: -3,
  },
  {
    value: "F",
    gap: 3,
  },
  {
    value: "G",
    gap: 0,
  },
  {
    value: "H",
    gap: -1,
  },
  {
    value: "I",
    gap: 9,
  },
];

let lastType = input[0].gap > 0 ? true : false;
const result = input.reduce((acc, curr) => {
      const { value, gap } = curr;

      if ((lastType && gap >= 0) || (!lastType && gap < 0))
        acc[acc.length - 1].push(curr);
      else {
        acc.push([curr]);
        lastType = !lastType;
      }
      return acc;
    },
    [[]]
  )
  .map((arr) => {
    const obj = { value: "", gap: 0 };
    for (let i = arr.length - 1; i >= 0; --i) {
      const { value, gap } = arr[i];
      obj["value"] = value;
      obj["gap"] += gap;
    }
    return obj;
  });

console.log(result);

2)

let input = [
  {
    value: "A",
    gap: 1,
  },
  {
    value: "B",
    gap: 2,
  },
  {
    value: "C",
    gap: 3,
  },
  {
    value: "D",
    gap: -2,
  },
  {
    value: "E",
    gap: -3,
  },
  {
    value: "F",
    gap: 3,
  },
  {
    value: "G",
    gap: 0,
  },
  {
    value: "H",
    gap: -1,
  },
  {
    value: "I",
    gap: 9,
  },
];
const accumulator = [[{ ...input[0], gap: 0 }]];

let lastType = input[0].gap > 0 ? true : false;
const result = input.reduce((acc, curr) => {
    const { value, gap } = curr;

    if ((lastType && gap >= 0) || (!lastType && gap < 0)) {
      lastEl = acc[acc.length - 1][0].gap += gap;
    } else {
      acc.push([curr]);
      lastType = !lastType;
    }
    return acc;
  }, accumulator)
  .flat();

console.log(result);

3) 感谢 cars10m 提供以下解决方案

let input = [{
    value: "A",
    gap: 1,
  },
  {
    value: "B",
    gap: 2,
  },
  {
    value: "C",
    gap: 3,
  },
  {
    value: "D",
    gap: -2,
  },
  {
    value: "E",
    gap: -3,
  },
  {
    value: "F",
    gap: 3,
  },
  {
    value: "G",
    gap: 0,
  },
  {
    value: "H",
    gap: -1,
  },
  {
    value: "I",
    gap: 9,
  },
];
const res = input.reduce((a, c) => {
  if (c.gap !== 0) {
    let lasta = a[a.length - 1];
    if (lasta && lasta.gap > 0 == c.gap > 0) lasta.gap += c.gap;
    else a.push(c);
  }
  return a;
}, []);

console.log(res);