Skip to content

Instantly share code, notes, and snippets.

@jeena
Created August 2, 2012 22:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeena/3241196 to your computer and use it in GitHub Desktop.
Save jeena/3241196 to your computer and use it in GitHub Desktop.
#!/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