list-to-tree
list-to-tree copied to clipboard
Consider dynamic parent/child matching fn()
https://github.com/DenQ/list-to-tree/blob/06f51966783687eff82645b96de136a6a8bd2853/dist/list-to-tree.js#L39
I have a need to generate a tree from a collection (array of objects). But my paths are nested - eg:
{
id: 100,
field: 'val',
// ...
meta: {
parent: 'abc-123'
}
}
I need to either pass dot-notation paths (and use a third party lib, like _ or object-path) or, to avoid dependencies, perhaps consider passing a matching fn to the constructor, which I can use third party libs without affecting deps on this module.
// list-to-tree constructor - add new param to end
constructor(list, options = {}, matcher) {
const _list = list.map((item) => item);
options = Object.assign({}, defaultOptions, options);
this.options = options;
const { key_id, key_parent } = options;
sortBy(_list, key_parent, key_id);
const tree = new IronTree({ [key_id]: 0 });
_list.forEach((item, index) => {
tree.add((parentNode) => {
// crude example below:
return matcher ? matcher(item, key_id, parentNode, key_parent) : parentNode.get(key_id) === item[key_parent];
}, item);
});
this.tree = tree;
}
Then you could pass whatever id-to-id matching fns you need.
// my application code
const objectPath = require('object-path')
matcher = function (item, key_id, parentNode, key_parent) {
return objectPath.get(parentNode, key_id) === objectPath.get(item, key_parent)
}
Now I can use:
new Tree(list, {
key_id: 'id',
key_parent: 'meta.parent'
}, matcher)
Thoughts?
@tremendus good idea! I have a lot of work right now. I can do this next week. Or you can transform your list now.
...
{
meta: {
parent: 'abc-123'
}
}
to
...
{
parent: 'abs-123',
meta: {
parent: 'abc-123'
}
}