'Array by percentage of the previous value [closed]

I have an array of strings, amount and a percentage.

Every key is found in the object. Its value is equal to the previous value plus the percentage.

This is the code I wrote:

const keys = ['a', 'b', 'c'];
const amount = 300;
const precentage = 0.5;
const obj = {};
let prevAmount = amount;
for (let i = 0; i < keys.length; i++) {
   if (i !== 0) {
     obj[keys[i]] = prevAmount + prevAmount * precentage;
     prevAmount = prevAmount + prevAmount * precentage;
   } else {
     obj[keys[i]] = amount;
     prevAmount = amount;
   }
}

The obj is:

{a: 300, b: 450, c: 675}

I don't like this code. It looks too long for me.

Is there a way to make it more readable and short?



Solution 1:[1]

You can simply track the previous amount and update it on each iteration.

const keys = ['a', 'b', 'c'];
const amount = 300;
const percentage = 0.5;

const result = {};

let prev = amount;
for (const key of keys) {
  result[key] = prev;
  prev = prev + (prev * percentage);
}

console.log(result)

Solution 2:[2]

you can do it using reduce

const createObj = (keys, amount, percentage) => keys.reduce((res, key, i) => {
  if (i === 0)
    return res
  return {
    ...res,
    [key]: res[keys[i - 1]] * (1.0 + percentage)
  }
}, {
  [keys[0]]: amount
})


const keys = ['a', 'b', 'c'];
const amount = 300;
const precentage = 0.5;


const result = createObj(keys, amount, precentage)

console.log(result)

Solution 3:[3]

Maybe use reduce with an accumulator that consists of the accumulated object and the accumulated amount?

const keys = ['a', 'b', 'c'];
const amount = 300;
const percentage = 0.5;

const obj = keys.reduce(({obj, amount}, key) => (
    obj[key] = amount, {obj, amount: amount * (1 + percentage)}
), {obj: {}, amount}).obj;

console.log(obj); //{a: 300, b: 450, c: 675}

Solution 4:[4]

Here I didn't use a separate variable to store the prevAmount. You can grab it from the object itself.

First assign the initial amount to the object as it does not change.

Then iterate the key array from the index 1 not from the index 0.

const keys = ["a", "b", "c"];
const amount = 300;
const precentage = 0.5;
const obj = {};

obj[keys[0]] = amount;

for (let i = 1; i < keys.length; i++) {
  obj[keys[i]] = obj[keys[i - 1]] * (precentage + 1);
}

console.log(obj);

Solution 5:[5]

You can use Array.prototype.reduce and reduce the keys array into the desired object.

const 
  keys = ["a", "b", "c"],
  amt = 300,
  percentage = 0.5,
  res = keys.reduce((r, k, i, a) => ((r[k] = i > 0 ? r[a[i - 1]] * (1 + percentage) : amt), r), {});

console.log(res);

Solution 6:[6]

Another way:

const keys = ['a', 'b', 'c'];
const amount = 300;
const precentage = 0.5;
const obj = {};
keys.reduce((prev, current, index) => {
  obj[current] = prev + (index == 0 ? 0 : amount * precentage)
  return (obj[current])
}, amount)
console.log(obj)

Solution 7:[7]

this could be another solution.

const keys = ['a', 'b', 'c'];
const amount = 300;
const percentage = 0.5;

function makeObj(keys, amount, percentage) {
  const result = {
    [keys[0]]: amount,
  };

  keys.forEach((k, i, arr) => {
    if (i === 0) return;

    const prevValue = result[arr[i - 1]];
    result[k] = prevValue + prevValue * percentage;
  });

  return result;
}

makeObj(keys, amount, percentage);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 R4ncid
Solution 3 trincot
Solution 4
Solution 5 SSM
Solution 6 VMT
Solution 7