@tabular-json/tabular-json
Version:
Tabular-JSON: a superset of JSON with CSV-like tables
59 lines • 1.83 kB
JavaScript
import { isObject } from './objects.js';
const leaf = Symbol();
export function isTabular(value) {
return Array.isArray(value) && value.length > 0 && value.every(isObject);
}
export function collectFields(array) {
const merged = {};
array.forEach((item) => {
if (isObject(item)) {
_mergeObject(item, merged);
}
else {
_mergeValue(item, merged);
}
});
const paths = [];
_collectPaths(merged, [], paths);
return paths;
}
// internal function for collectNestedPaths
// mutates the argument `merged`
function _mergeObject(object, merged) {
for (const key in object) {
const value = object[key];
const valueMerged = merged[key] || (merged[key] = (Array.isArray(value) ? [] : {}));
if (isObject(value)) {
_mergeObject(value, valueMerged);
}
else {
_mergeValue(value, valueMerged);
}
}
}
// internal function for collectNestedPaths
// mutates the argument `merged`
function _mergeValue(value, merged) {
if (merged[leaf] === undefined) {
merged[leaf] = value === null || value === undefined ? null : true;
}
}
// internal function for collectNestedPaths
// mutates the argument `paths`
function _collectPaths(merged, parentPath, paths) {
if (merged[leaf] === true || (merged[leaf] === null && isEmpty(merged))) {
paths.push(parentPath);
}
else if (Array.isArray(merged)) {
merged.forEach((item, index) => _collectPaths(item, parentPath.concat(index), paths));
}
else if (isObject(merged)) {
for (const key in merged) {
_collectPaths(merged[key], parentPath.concat(key), paths);
}
}
}
function isEmpty(object) {
return Object.keys(object).length === 0;
}
//# sourceMappingURL=tabular.js.map