Home > Net >  How to compute the average of a set of numbers inside a nested object within an array?
How to compute the average of a set of numbers inside a nested object within an array?

Time:11-24

I have the following object with a set of colors for each shape:

const design = {
      designId: 1,
      shapes: [
        { shapeId: 'basic-square', color: { r: 255, g: 255, b: 255 }},
        { shapeId: 'basic-circle', color: { r: 255, g: 255, b: 255 }},
        { shapeId: 'basic-diamond', color: { r: 255, g: 0, b: 0 }},
        { shapeId: 'basic-rectangle', color: { r: 0, g: 255, b: 0 }}
      ]
    }

I want to return the following output which computes the average of each color per design object:

Design 1: {r: 191.25, g: 191.25, b: 127.5 }

Keeping in mind Big O, what's the an efficient way to solve this problem?

Here is my attempt, however I was told it was not efficient enough:

const average = (arr) => arr.reduce((a, b) => a   b, 0) / arr.length;

const { shapes } = design;

const reds = shapes.map(shape => shape.color.r)
const greens = shapes.map(shape => shape.color.g)
const blues = shapes.map(shape => shape.color.b)

console.log(`Design ${design.designId}: {r: ${average(reds)}, g: ${average(greens)}, b: ${average(blues)} }`)

CodePudding user response:

Your solution is O(6N) so it's O(N). I would've used a reduce however.

const design = {
      designId: 1,
      shapes: [
        { shapeId: 'basic-square', color: { r: 255, g: 255, b: 255 }},
        { shapeId: 'basic-circle', color: { r: 255, g: 255, b: 255 }},
        { shapeId: 'basic-diamond', color: { r: 255, g: 0, b: 0 }},
        { shapeId: 'basic-rectangle', color: { r: 0, g: 255, b: 0 }}
      ]
    };

const { shapes, designId  } = design;

const average = shapes.reduce((acc, curr) => ({
  red: acc.red   curr.color.r / shapes.length,
  green: acc.green   curr.color.g / shapes.length,
  blue: acc.blue   curr.color.b / shapes.length
  }), {
  red: 0, green: 0, blue: 0
  }
 );



console.log(`Design ${designId}: {r: ${average.red}, g: ${average.green}, b: ${average.blue}`)

CodePudding user response:

Your attempt is O(6n) (which is for all intents and purposes O(n)) but you can do it in O(1n) in a single reduce() call or for loop.

const design = {
  designId: 1,
  shapes: [
    { shapeId: 'basic-square', color: { r: 255, g: 255, b: 255 } },
    { shapeId: 'basic-circle', color: { r: 255, g: 255, b: 255 } },
    { shapeId: 'basic-diamond', color: { r: 255, g: 0, b: 0 } },
    { shapeId: 'basic-rectangle', color: { r: 0, g: 255, b: 0 } }
  ]
}

const sums = { r: 0, g: 0, b: 0 };
for (const { color: { r, g, b } } of design.shapes) {
  sums.r  = r
  sums.g  = g;
  sums.b  = b;
}

const len = design.shapes.length;
const result = {
  [`Design ${design.designId}`]: {
    r: sums.r / len,
    g: sums.g / len,
    b: sums.b / len
  }
}

console.log(result);

CodePudding user response:

Use a for loop and move the Array.map() part into the average() function

const design = {
      designId: 1,
      shapes: [
        { shapeId: 'basic-square', color: { r: 255, g: 255, b: 255 }},
        { shapeId: 'basic-circle', color: { r: 255, g: 255, b: 255 }},
        { shapeId: 'basic-diamond', color: { r: 255, g: 0, b: 0 }},
        { shapeId: 'basic-rectangle', color: { r: 0, g: 255, b: 0 }}
      ]
    };

//Design 1: {r: 191.25, g: 191.25, b: 127.5 }

function average(color) {
  let result = 0;
  for(let i=0; i<design.shapes.length; i  ) {
    result  = design.shapes[i].color[color]
  }
  return result / design.shapes.length;
}

console.log(`Design ${design.designId}: {r: ${average('r')}, g: ${average('g')}, b: ${average('b')} }`)

  • Related