admin管理员组

文章数量:1401158

I have one question regarding the good usage of Array.reduce in Javascript. Supposing I have an array with some simple objects like this:

let values = [{value: 2}, {value: 3}, {value: 8}, {value: 11}];

And I want to add a "diff" property to each object to pute the difference between the current item value and the previous item value. I want something like this:

let values = [
  {value: 2}, 
  {value: 3, diff: 1}, 
  {value: 8, diff: 5}, 
  {value: 11, diff: 3}
];

To achieve this I decided to use the Array.reduce method. I´m using reduce because I can access the current item as well as the latest item but I´m not interested in the reduced array in this case.

values.reduce((acc, cur) => {
  if (acc.value) {
    cur.diff = cur.value - acc.value;
  }
  return cur;
}, {});

Is this a good usage of Array.reduce? I don´t like the way I´m mutating the items of the original array but on the other way reduce is the only array method that can access the previous item. Maybe a simple for-of loop should be better in this case?

Thanks

I have one question regarding the good usage of Array.reduce in Javascript. Supposing I have an array with some simple objects like this:

let values = [{value: 2}, {value: 3}, {value: 8}, {value: 11}];

And I want to add a "diff" property to each object to pute the difference between the current item value and the previous item value. I want something like this:

let values = [
  {value: 2}, 
  {value: 3, diff: 1}, 
  {value: 8, diff: 5}, 
  {value: 11, diff: 3}
];

To achieve this I decided to use the Array.reduce method. I´m using reduce because I can access the current item as well as the latest item but I´m not interested in the reduced array in this case.

values.reduce((acc, cur) => {
  if (acc.value) {
    cur.diff = cur.value - acc.value;
  }
  return cur;
}, {});

Is this a good usage of Array.reduce? I don´t like the way I´m mutating the items of the original array but on the other way reduce is the only array method that can access the previous item. Maybe a simple for-of loop should be better in this case?

Thanks

Share Improve this question asked Mar 6, 2017 at 14:10 Federico GarcíaFederico García 1412 silver badges9 bronze badges 2
  • From the doc : The reduce() method applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value. – Weedoze Commented Mar 6, 2017 at 14:15
  • 1 It is personal preference if it is good usage. You are using reduce to hold a value instead of its intended purpose. Some people will find it smart, others will hate it. – epascarello Commented Mar 6, 2017 at 14:16
Add a ment  | 

2 Answers 2

Reset to default 7

You could use Array#forEach, because you have already the access to the predecessor.

The advantage is, you do not have the overhead of having a return value.

let values = [{ value: 2 }, { value: 3 }, { value: 8 }, { value: 11 }];

values.forEach((a, i, aa) => i && (a.diff = a.value - aa[i - 1].value));

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

You can also use map() in case you don't want to mutate the original array / items.

const values = [{ value: 2 }, { value: 3 }, { value: 8 }, { value: 11 }];

const diff = values.map(
  ({ value }, i, arr) => ({
    value,
    // add `diff` property if not first element
    ...(i && { diff: value - arr[i - 1].value }),
  }),
);

console.log(diff);

本文标签: javascriptUse reduce to mutate array items Bad patternStack Overflow