求助纯 JavaScript 代码优化

50 天前
 zzlit
const originArr = [
  {
    value: 'q',
    children: [
      {
        value: 'w',
        children: [{ value: 'e' }, { value: 'r' }]
      },
      {
        value: 't',
        children: [{ value: '' }, { value: 'y' }, { value: 'u' }]
      },
      { value: 'i' }
    ]
  },
  {
    value: 'o'
  }
];

const targetMap = new Map([
  ['q/w/e', undefined],
  ['q/t', undefined]
]);

function formatArr(arr, path) {
  for (let idx = arr.length - 1; idx >= 0; idx--) {
    const i = arr[idx];
    let mapKey = arr[idx].value;
    if (path) mapKey = `${path}${mapKey ? '/' : ''}${mapKey}`;

    let flag = true;
    let finish = false;

    targetMap.forEach((value, key) => {
      if (key === mapKey) {
        finish = true;
      } else {
        const index = key.indexOf(mapKey);
        if (flag && index === 0) flag = false;
      }
    });
    if (finish) continue;

    if (flag) {
      arr.splice(idx, 1);
      continue;
    }

    if (i.children) formatArr(i.children, mapKey);
  }
}

const copyArr = JSON.parse(JSON.stringify(originArr));
formatArr(copyArr);

console.log(originArr, copyArr);

作用是根据一个 map 对象去找一个数组里面嵌套的值,表达可能不太清楚,代码能直接跑起来,输出一眼能看出来是干嘛的。求助大佬们这段代码怎么优化?感觉有很大的优化空间

976 次点击
所在节点    程序员
10 条回复
SHF
50 天前
笑死,连要解决的问题都没法描述清楚,直接丢了一坨代码要人看输出去猜,你这个要优化的不是代码,是你编程的思路。
summerwar
50 天前
你直接把代码贴给 AI 吧,然后他会帮你优化下
LavaC
50 天前
zsh2517
50 天前
贴个运行结果

![]( https://sm.ms/image/y1icwg9HCLaRq7N)

代码读不下去。从运行结果以及粗略扫过的代码来看。大概是

targetMap 定义了一些路径(这里没必要叫做 map ,没用到 value )。
originArr 是一个数字,假设这里的类型是 obj ,大概相当于是 interface obj {value: string, children?: obj[])

然后,对 map 里面每一项 key ,按照 obj.value 作为目录名的完整路径,选择前缀能匹配 obj.value 的东西保留,其他删掉
zzlit
49 天前
@SHF v2 贴图不太方便,不然直接贴图了。我想的是 f12 贴代码就能看到运行输出结果了,不过确实我也还是需要描述一下解决的问题的,不然每个人读代码都会有不同的见解
zzlit
49 天前
@LavaC 感谢大佬
zzlit
49 天前
@zsh2517 确实应该直接描述问题然后再贴代码比较合适,直接贴代码会读不下去
zsh2517
49 天前
@zzlit #7 主要最近比较忙。本来想写一下试试,打开 IDE 看了一会,不想动脑子了😂
x4storm
49 天前
原始的代码确实难读:手动 for 循环;各种 flag 用于控制循环。这些面向过程式的编程风格极大的增加了阅读难度。

以下是 AI 优化过的代码,利用 js 的函数式编程特性,可以以更易读的方式组织代码:
主要的优化点是,用 filter 和 some 代替冗长的 for 循环。这里面的 Map 确实不是必要的,如果换成 string array 的话看起来会更简单一点。

```javascript
const originArr = [
{ value: "q", children: [{ value: "w", children: [{ value: "e" }, { value: "r" }] }, { value: "t", children: [{ value: "" }, { value: "y" }, { value: "u" }] }, { value: "i" }] },
{ value: "o" },
];

const targetMap = new Map([
["q/w/e", undefined],
["q/t", undefined],
]);

function formatArr(arr, path = '') {
return arr.filter(item => {
const currentPath = path ? `${path}/${item.value}` : item.value;

// Check if the current path is needed
if (targetMap.has(currentPath)) {
return true;
}

// Check if any target path starts with the current path
const isPrefix = Array.from(targetMap.keys()).some(key => key.startsWith(currentPath));
if (!isPrefix) {
return false;
}

// Recursively filter children if they exist
if (item.children) {
item.children = formatArr(item.children, currentPath);
}

return true;
});
}

const copyArr = formatArr(JSON.parse(JSON.stringify(originArr)));
console.log(originArr, copyArr);
```
zzlit
49 天前
@x4storm 多谢大佬,学习了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1038536

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX