Created
May 8, 2022 10:09
-
-
Save julio73/f074c1a4ce7398f9b2aa28238b50cbcf 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
/** | |
* 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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
flattenTree function in https://gist.github.com/julio73/c24b48f690008ac4862edfffb337d35c