如何将插件对象数组转换为UI库要求的指定树形结构?
Hey there! I totally get where you’re coming from—transforming that flat plugin array into a nested tree structure can feel like a slog if you’re stuck with manual loops or messy groupBy chains. Let me walk you through a clean, scalable solution that avoids repetitive code, whether you want to use Lodash or stick to vanilla JavaScript.
The Core Idea
We need to recursively group your plugins by the hierarchy you defined: pluginId → pcVersion → pluginVersion → platform. Instead of writing nested loops for each level, we’ll create a reusable function that handles any number of grouping layers.
Solution 1: Using Lodash (Concise & Powerful)
Lodash’s groupBy is perfect here, but we’ll pair it with recursion to avoid repetitive code. We’ll also add a quick platform name mapping to match your target structure (e.g., win → windows).
const _ = require('lodash'); // Map platform codes to friendly names (matches your target structure) const PLATFORM_NAME_MAP = { win: 'windows', mac: 'mac', linux: 'linux' }; function buildPluginTree(plugins) { // Define our grouping hierarchy (easy to adjust if levels change later) const hierarchy = ['pluginId', 'pcVersion', 'pluginVersion', 'platform']; // Recursive function to group and transform each level function groupLevel(items, levelIndex) { // At the lowest level, return the plugin objects themselves if (levelIndex >= hierarchy.length) { return items; } const currentKey = hierarchy[levelIndex]; const groupedItems = _.groupBy(items, currentKey); // Convert each group into a tree node return Object.entries(groupedItems).map(([key, children]) => { // Use friendly platform name for the final level const nodeName = levelIndex === 3 ? PLATFORM_NAME_MAP[key] || key : key; return { name: nodeName, children: groupLevel(children, levelIndex + 1) }; }); } return groupLevel(plugins, 0); } // Example usage with your plugin array const rawPlugins = [/* Your original plugin array here */]; const pluginTree = buildPluginTree(rawPlugins); console.log(JSON.stringify(pluginTree, null, 2));
Solution 2: Vanilla JavaScript (No Dependencies)
If you don’t want to rely on Lodash, we can replicate the grouping logic with reduce and keep the same recursive structure:
// Map platform codes to friendly names const PLATFORM_NAME_MAP = { win: 'windows', mac: 'mac', linux: 'linux' }; function buildPluginTree(plugins) { const hierarchy = ['pluginId', 'pcVersion', 'pluginVersion', 'platform']; // Custom groupBy function using reduce function groupBy(arr, key) { return arr.reduce((acc, item) => { const groupKey = item[key]; acc[groupKey] = acc[groupKey] || []; acc[groupKey].push(item); return acc; }, {}); } // Recursive level grouping function groupLevel(items, levelIndex) { if (levelIndex >= hierarchy.length) { return items; } const currentKey = hierarchy[levelIndex]; const groupedItems = groupBy(items, currentKey); return Object.entries(groupedItems).map(([key, children]) => { const nodeName = levelIndex === 3 ? PLATFORM_NAME_MAP[key] || key : key; return { name: nodeName, children: groupLevel(children, levelIndex + 1) }; }); } return groupLevel(plugins, 0); } // Example usage const rawPlugins = [/* Your original plugin array here */]; const pluginTree = buildPluginTree(rawPlugins); console.log(JSON.stringify(pluginTree, null, 2));
Why This Works
- Scalability: If you ever need to add or remove grouping levels (e.g., add a
categorylevel), just update thehierarchyarray—no need to rewrite core logic. - Cleanliness: Recursion eliminates nested loops, making the code easier to read and maintain.
- Flexibility: The platform name mapping is easy to adjust if you need to support more platforms later.
This will output exactly the tree structure you need, matching the UI library’s requirements.
内容的提问来源于stack exchange,提问作者gameFrenzy07

