d3plus-common
Version:
Common functions and methods used across D3plus modules.
61 lines (60 loc) • 2.25 kB
JavaScript
import { merge, sum } from "d3-array";
import unique from "./unique.js";
/**
@function merge
@desc Combines an Array of Objects together and returns a new Object.
@param {Array} objects The Array of objects to be merged together.
@param {Object} aggs An object containing specific aggregation methods (functions) for each key type. By default, numbers are summed and strings are returned as an array of unique values.
@example <caption>this</caption>
merge([
{id: "foo", group: "A", value: 10, links: [1, 2]},
{id: "bar", group: "A", value: 20, links: [1, 3]}
]);
@example <caption>returns this</caption>
{id: ["bar", "foo"], group: "A", value: 30, links: [1, 2, 3]}
*/
function objectMerge(objects) {
var aggs = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var availableKeys = unique(merge(objects.map(function (o) {
return Object.keys(o);
}))),
newObject = {};
availableKeys.forEach(function (k) {
var value;
if (aggs[k]) value = aggs[k](objects, function (o) {
return o[k];
});else {
var values = objects.map(function (o) {
return o[k];
});
var types = values.map(function (v) {
return v || v === false ? v.constructor : v;
}).filter(function (v) {
return v !== void 0;
});
if (!types.length) value = undefined;else if (types.indexOf(Array) >= 0) {
value = merge(values.map(function (v) {
return v instanceof Array ? v : [v];
}));
value = unique(value);
if (value.length === 1) value = value[0];
} else if (types.indexOf(String) >= 0) {
value = unique(values);
if (value.length === 1) value = value[0];
} else if (types.indexOf(Number) >= 0) value = sum(values);else if (types.indexOf(Object) >= 0) {
value = unique(values.filter(function (v) {
return v;
}));
if (value.length === 1) value = value[0];else value = objectMerge(value);
} else {
value = unique(values.filter(function (v) {
return v !== void 0;
}));
if (value.length === 1) value = value[0];
}
}
newObject[k] = value;
});
return newObject;
}
export default objectMerge;