Files
DiceCloud/app/imports/api/creature/computation/newEngine/applyFnToKey.js

47 lines
1.2 KiB
JavaScript

import { get } from 'lodash';
export function applyFnToKey(doc, key, fn){
if (key.includes('$.')){
applyToArrayKey(doc, key, fn);
} else {
applyToSingleKey(doc, key, fn);
}
}
function applyToSingleKey(doc, key, fn){
// call the function with the current value and document for context
fn(doc, key);
}
/**
* Applies the given function to all instances in a document key
* key.$.with.$.subdocs will apply to all key[i...n].with[j...m].subdocs
*/
function applyToArrayKey(doc, key, fn){
const keySplit = key.split('.$');
// Stack based depth first traversal of arrays
const stack = [{
array: get(doc, keySplit[0]),
paths: keySplit.slice(1),
currentPath: keySplit[0],
indices: [],
}];
while(stack.length){
const state = stack.pop();
for (let index in state.array.length){
const currentPath = `${state.currentPath}[${index}]${state.paths[0]}`
if (state.paths.length == 1){
applyToSingleKey(doc, currentPath, fn);
} else {
stack.push({
array: get(doc, currentPath),
paths: state.paths.slice(1),
currentPath,
indices: [...state.indices, index],
});
}
}
}
}