Created
August 2, 2012 22:14
-
-
Save jeena/3241196 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
function makeAverages (data) { | |
// JS has no block scope only function scope, so it is better to | |
// declare all variables at the top of the function. | |
var measurements = [], | |
categories = {}, | |
out_rows = [], | |
measurement, i, row, category_name, measurement_name, is_error, | |
category, average; | |
// Loop through all lines in the table and add values and count errors, etc. | |
for (i = 0; i < data.length; i++) { | |
// Just for easier reading | |
row = data[i]; | |
category_name = row.category; | |
measurement_name = row.measurement; | |
is_error = row.value == "ERROR"; | |
category = categories[category_name]; | |
// Add measurement if not yet added | |
if (measurements.indexOf(measurement_name) == -1) { | |
measurements.push(measurement_name); | |
} | |
// Add category if not yet added | |
if (!category) { | |
category = {}; | |
categories[category_name] = category; | |
} | |
// Add a new measurement with default data if not yet added | |
measurement = category[measurement_name]; | |
if (!measurement) { | |
measurement = { amount: 0, errors: 0, value: 0 }; | |
category[measurement_name] = measurement; | |
} | |
// Populate measurement adding one when counting | |
// or the value if it is not an error | |
measurement.amount += is_error ? 0 : 1; | |
measurement.errors += is_error ? 1 : 0; | |
measurement.value += is_error ? 0 : row.value; | |
} | |
// Add title row | |
row = ["Category"]; | |
// Loop through measurements and add them to the title row | |
for (i = 0; i < measurements.length; i++) { | |
measurement_name = measurements[i]; | |
row.push(measurement_name + " average"); | |
row.push(measurement_name + " errors"); | |
} | |
out_rows.push(row); | |
// Add a row per category | |
for (category_name in categories) { | |
// Make new row and add the category name | |
row = [category_name]; | |
// Loop through all measurements, even if the category doesn't | |
// have such a measurement | |
for (i = 0; i < measurements.length; i++) { | |
measurement_name = measurements[i]; | |
measurement = categories[category_name][measurement_name]; | |
// calculate average | |
average = 0; | |
if (measurement && measurement.amount > 0) { | |
average = measurement.value / measurement.amount; | |
} | |
// Add average and error count to this row | |
if (measurement) { | |
row.push(average); | |
row.push(measurement.errors); | |
} else { | |
// If this category has no such measurement then add | |
// just hyphens as average and error count | |
row.push("-"); | |
row.push("-"); | |
} | |
} | |
out_rows.push(row); | |
} | |
return out_rows; | |
} | |
var data = [ | |
{ category: "A", measurement: "a", value: 2 }, | |
{ category: "A", measurement: "b", value: "ERROR" }, | |
{ category: "A", measurement: "a", value: "ERROR" }, | |
{ category: "B", measurement: "a", value: "ERROR" }, | |
{ category: "B", measurement: "b", value: 3 }, | |
{ category: "B", measurement: "b", value: 5 }, | |
{ category: "B", measurement: "c", value: 7.12 }, | |
{ category: "B", measurement: "c", value: 77 }, | |
{ category: "B", measurement: "c", value: "ERROR" }, | |
]; | |
console.log(makeAverages(data)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment