0

I have an array of objects as follows. Each object has an array P2 inside it.

let input = [ 
     { "P2": [ 6, 6, 0 ] },
     { "P2": [ 3, 2, 0 ] },
     { "P2": [ 5, 1, 0 ] },
]

I want the desired result. as you can see, i am adding the elements and putting the result in the last element. for e.g. adding 6+6+0 and putting the result in last element as 12. Similarly for other objects inside the array. So the final output will look like this.

   [ 
     { "P2": [ 6, 6, 0, 12 ] },
     { "P2": [ 3, 2, 0, 5 ] },
     { "P2": [ 5, 1, 0, 6 ] },
   ]

I am able to achieve this with a simple loop and reduce function as shown below.

input.forEach(arrayItem => {
  let sum = arrayItem.P2.reduce((partialSum, a) => partialSum + a, 0);
  arrayItem.P2.push(sum)
});

console.log(input)

Its fine till here. but it gets really interesting when i have dynamic input. for e.g. inside for static P2 values, i can have anything else. For e.g. shown below are the 2 examples of dynamic input.

let input = [ 
     { "P1": [ 6, 6, 0 ] },
     { "P2": [ 3, 2, 0 ] },
     { "P3": [ 5, 1, 0 ] },
]

OR

let input = [ 
     { "P2": [ 3, 3, 3, 2 ] },
     { "P2": [ 7, 7, 7, 4 ] },
     { "Total": [ 5, 1, 4, 6 ] },
]

Can someone let me know how to modify my code if there is dynamic property names like this.

5
  • ?? What's the "dynamic" part?
    – Pointy
    Commented May 8 at 15:46
  • the property names, p2 p3, total
    – Aren Trot
    Commented May 8 at 15:47
  • 3
    Well you can use Object.keys() to get an array of property names, and then iterate through that however you want.
    – Pointy
    Commented May 8 at 15:48
  • 2
    If it's always the last item in the array, you can use input[input.length-1] to get the last element and Object.keys(input[input.length-1])[0] to get its key value.
    – mykaf
    Commented May 8 at 15:48
  • 2
    The second problem isn't really all that interesting, it looks more like someone's code is using the wrong data structure entirely to capture data: why do they have different property names, and can you fix the code that does that instead? (Because trying to compensate for it later just puts a bandaid over an already bad choice, let's fix things where they go wrong, instead?) Commented May 8 at 15:49

4 Answers 4

2

you can iterate over each object in the array and dynamically access the property name using Object.keys() or Object.entries().

let input = [ 
    { "P1": [ 6, 6, 0 ] },
    { "P2": [ 3, 2, 0 ] },
    { "P3": [ 5, 1, 0 ] },
];

input.forEach(arrayItem => {
    let propertyName = Object.keys(arrayItem)[0];
    let values = arrayItem[propertyName];
    let sum = values.reduce((partialSum, value) => partialSum + value, 0);
    values.push(sum);
});

console.log(input);

Using your second example

let input = [ 
     { "P2": [ 3, 3, 3, 2 ] },
     { "P2": [ 7, 7, 7, 4 ] },
     { "Total": [ 5, 1, 4, 6 ] },
]

input.forEach(arrayItem => {
    let propertyName = Object.keys(arrayItem)[0];
    let values = arrayItem[propertyName];
    let sum = values.reduce((partialSum, value) => partialSum + value, 0);
    values.push(sum);
});

console.log(input);

1

Just iterate and push a sum as the last element to the sub arrays:

let input = [ 
     { "P1": [ 6, 6, 0 ] },
     { "P2": [ 3, 2, 0 ] },
     { "P3": [ 5, 1, 0 ] },
]

input.forEach(item => {
  const [arr] = Object.values(item);
  arr.push(arr.reduce((r, n) => r+n));
});
console.log(input);

1

You may also use the array map method as follows:

let input = [ 
     { "P2": [ 6, 6, 0 ] },
     { "P2": [ 3, 2, 0 ] },
     { "P2": [ 5, 1, 0 ] },
];

input = input.map(({P2}) => ({P2:[...P2,P2.reduce((a,c) => a+c,0)]}));

console.log( input );

Now for this, you can use the array map method and Object.keys() and Object.values():

let input = [ 
     { "P1": [ 6, 6, 0 ] },
     { "P2": [ 3, 2, 0 ] },
     { "P3": [ 5, 1, 0 ] },
];

input = input.map(o => ({
    [Object.keys(o)[0]]: [
        ...Object.values(o)[0],
        Object.values(o)[0].reduce((a,c) => a+c,0)
    ]})
);

console.log( input );

And similarly for this one:

let input = [ 
     { "P2": [ 3, 3, 3, 2 ] },
     { "P2": [ 7, 7, 7, 4 ] },
     { "Total": [ 5, 1, 4, 6 ] },
];

input = input.map(o => ({
    [Object.keys(o)[0]]: [
        ...Object.values(o)[0],
        Object.values(o)[0].reduce((a,c) => a+c,0)
    ]})
);
        
        
console.log( input );

Or, if you choose to use Object.entries() and Object.fromEntries:

let input = [ 
     { "P2": [ 3, 3, 3, 2 ] },
     { "P2": [ 7, 7, 7, 4 ] },
     { "Total": [ 5, 1, 4, 6 ] },
];

input = input.map(o => Object.fromEntries(
        Object.entries(o).map(
            ([key,values]) => [
                key,
                [...values,values.reduce((a,c) => a+c,0)]
            ]
        )
    )
);
        
        
console.log( input );

1

The problem with your code is that you are using arrayItem.P2 in the function and expecting it to access every object inside the array. It will only work for 'P2' and won't work for any other keys like 'P1', 'P3' and like that. So you need to access the array without explicitly mentioning the key names. For this you can use Object.keys method. In your case you should be using Object.keys(arrayItem) to access the array inside the objects.

input.forEach((arrayItem) => {
  let key = Object.keys(arrayItem);
  const sum = arrayItem[key]
    .reduce((a, b) => {
      a += b;
      return a;
    });
  arrayItem[key].push(sum);
});

console.log(input)
<script>
  let input = [{
      "P1": [6, 6, 0]
    },
    {
      "P2": [3, 2, 0]
    },
    {
      "P3": [5, 1, 0]
    },
  ]
</script>

Not the answer you're looking for? Browse other questions tagged or ask your own question.