Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save julio73/f074c1a4ce7398f9b2aa28238b50cbcf to your computer and use it in GitHub Desktop.
Save julio73/f074c1a4ce7398f9b2aa28238b50cbcf to your computer and use it in GitHub Desktop.
/**
* Builds an array of object structure from an object with parallel values.
* Expects the same number of entries in each array.
* Similar to building a pivot table, but with a tree structure.
*
* @param data Object with parallel values in arrays.
* @param separator String to use as a separator in the keys from the data.
* @returns Array of objects with the keys from the data and the values from the data arranged hierarchically.
* @example
* // The data is in the form:
* {
* "country": ["USA", "USA", "USA", null, "USA", null, "France"],
* "state": ["CA", "CA", "NY", null, "TX", "Michigan", null],
* "city": ["Los Angeles", "San Francisco", "New York", "Abidjan", null, null, "Paris"]
* }
*
* // The output should be:
* [{
* "label": "USA", "id": "USA", "children": [
* {
* "label": "CA", "id": "USA|CA", "children": [
* { "label": "Los Angeles", "id": "USA|CA|Los Angeles" },
* { "label": "San Francisco", "id": "USA|CA|San Francisco" }]
* },
* {
* "label": "NY", "id": "USA|NY", "children": [
* { "label": "New York", "id": "USA|NY|New York" }]
* },
* { "label": "TX", "id": "USA|TX" }
* ]
* },
* { "label": "Abidjan", "id": "||Abidjan" },
* { "label": "Michigan", "id": "|Michigan" },
* {
* "label": "France", "id": "France", "children": [
* { "label": "Paris", "id": "France||Paris" }]
* }]
*/
function buildAdvancedFieldLocationTreeArray(data, separator = "|") {
let dataTree = {};
let dataArray = [];
for (let i = 0; i < data.country.length; i++) {
const [country, state, city] = [data.country[i], (data.state ? data.state[i] : null), (data.city ? data.city[i] : null)];
// fill up the tree from country, state, and city
if (country && !(country in dataTree)) {
dataTree[country] = {
label: country,
id: country
};
}
if (country && state) {
dataTree[country].children = dataTree[country].children || {};
const stateKey = `${country}${separator}${state}`;
if (!(stateKey in dataTree[country].children)) {
dataTree[country].children[stateKey] = {
label: state,
id: stateKey
};
}
}
if (country && state && city) {
const stateKey = `${country}${separator}${state}`;
const cityKey = `${country}${separator}${state}${separator}${city}`;
dataTree[country].children[stateKey].children = dataTree[country].children[stateKey].children || {};
if (!(cityKey in dataTree[country].children[stateKey].children)) {
dataTree[country].children[stateKey].children[cityKey] = {
label: city,
id: cityKey
};
}
}
// fill up the tree for state and city
if (!country && state && city) {
const stateKey = `${separator}${state}`;
if (!(stateKey in dataTree)) {
dataTree[stateKey] = {
label: state,
id: stateKey
};
}
const cityKey = `${separator}${state}${separator}${city}`;
if (!(cityKey in dataTree[stateKey].children)) {
dataTree[stateKey].children[cityKey] = {
label: city,
id: cityKey
};
}
}
// fill up the tree for country and city
if (country && !state && city) {
const cityKey = `${country}${separator}${separator}${city}`;
dataTree[country].children = dataTree[country].children || {};
if (!(cityKey in dataTree[country].children)) {
dataTree[country].children[cityKey] = {
label: city,
id: cityKey
};
}
}
// fill up the tree for city only
if (!country && !state && city) {
const cityKey = `${separator}${separator}${city}`;
if (!(cityKey in dataTree)) {
dataTree[cityKey] = {
label: city,
id: cityKey
};
}
}
// fill up the tree for state only
if (!country && state && !city) {
const stateKey = `${separator}${state}`;
if (!(stateKey in dataTree)) {
dataTree[stateKey] = {
label: state,
id: stateKey
};
}
}
}
// flatten the tree structure for the custom widget
dataArray = flattenTree(dataTree);
return dataArray;
}
@julio73
Copy link
Author

julio73 commented May 8, 2022

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment