List item data structure
typescriptinterface ListItem { code: string; groupCode: string; }
List data structure
typescripttype List = ListImte[]
Auxiliary data structure when updating grouping
typescripttype GroupStack = { groupCode: string; index: number; // the real subscript of the group offsetNumber: number // the length of the group, for recording the relative position of the list items in the group }[]
The data structure used for react rendering
typescriptinterface AssistStruct { code: string; children?: AssistStruct[]; parentGroupCode?: string; //pop stack flag }
Detect group closure,The algorithm is a variant of the bracket closure algorithm.
If the group-code field in the current list item is not equal to the code at the top of the stack, the group is closed and the current stack top element is popped.
typescript/** * Convert a one-dimensional array to a multi-layer structure * @param compCodes The code of all components * @param compDatas the data of all components * @returns returns the nested structure associated with code, the */ const subList = (compCodes: string[], compDatas: JDV.State['compDatas']): AssistStruct[] => { let groupStack: GroupStack[] = []; const resultData: AssistStruct[] = []; const stackPop = (groupCode?: string) => { let len = groupStack.length - 1; while (len >= 0) { if (groupStack[len].groupCode ! == groupCode) { groupStack.pop(); } else { break; } len--; } }; const setResult = (result: AssistStruct[], groupStack: GroupStack[], groupCode: string, value: AssistStruct) => { groupStack.forEach((item, index) => { if (!result) { return null; } if (!result[item.index]) { return; } if (result[item.index].code ! == groupCode) { // If the current component's group is not equal to the key in the result, search down return setResult(result[item.index].children as AssistStruct[], groupStack.slice(index + 1), groupCode, value); } else { if (result[item.index].children) { (result[item.index].children as AssistStruct[]).push(value); item.offsetNumber += 1; } else { result[item.index].children = [value]; } } }); }; compCodes.forEach((item, index) => { const hasGroup = compDatas[item] ? compDatas[item].config.groupCode : undefined; stackPop(hasGroup); if (compDatas[item].compCode === 'group') { if (hasGroup) { // If the current component's parent is at the top of the stack, update the result tree setResult(resultData, groupStack.slice(0), hasGroup, { code: item, children: [], }); // if the current group has a parent group, the group stack must not be empty, and the group index is the parent group length-1 // debugger; groupStack.push({ groupCode: item, index: groupStack.length ? groupStack[groupStack.length - 1].offsetNumber - 1 : index, offsetNumber: 0, }); } else { groupStack = []; //no group, empty stack resultData.push({ code: item, children: [], }); //If the current group has no parent group, the group stack must be empty and the group index is the result length groupStack.push({ groupCode: item, index: resultData.length - 1, offsetNumber: 0, }); } } else { if (hasGroup) { // If the current component's parent is at the top of the stack, update the result tree setResult(resultData, groupStack.slice(0), hasGroup, { code: item, }); } else { groupStack = []; //no group, empty stack resultData.push({ code: item, }); } } }); return resultData;
Translated with www.DeepL.com/Translator (free version)