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')} }`)