首页 > 解决方案 > 试图提出一个可以在对象的特定级别上进行过滤的函数

问题描述

我有一个对象叫cache

const cache = {
  a: {
    b: { c: [toRemove1, toPreserve1, toRemove2, toPreserve2], d: "irrelevant" }
  }
}

这个对象是有类型的,所以我们可以确切地知道在哪里可以找到要删除的东西的级别

而我想toRemove1 toRemove2专门对 的层级进行过滤c,所以我们不需要关心 中的其他层级cache

过滤后的结果是 { a: { b: { c: [toPreserve1, toPreserve2] , d: 'irrelevant'} } }

我想出的功能是这个

function filter(cache, thingsToRemove, mapper) {
  const filtered = mapper(cache).filter(
    (thing) => !thingsToRemove.includes(thing)
  );
}

mapper是一个遍历到我们想要执行过滤的级别的函数。在这种情况下(cache) => cache.a.b.c

这是问题所在,虽然我当前的解决方案完成了过滤工作,但我似乎无法保留 的原始结构cache,这意味着mapper(cache).filter((thing) => !thingsToRemove.includes(thing))is的结果[toPreserve1, toPreserve2]。但我需要返回的对象具有与以前相同的结构。

这是现场演示:https ://codesandbox.io/s/still-feather-zuhcl?file=/src/index.js

我不确定当前的 API 是否有可能……如果没有,应该改变什么?

我也很清楚我们可以传递另一个参数来指示最后一个属性在哪里,在这种情况下是c. 但我真的希望不需要明确传递该参数来实现这一点。

我也知道我可以path在 API 中添加一个路径数组。例如["a", "b", "c"],但我的想法是找到一种方法来使用函数来遍历它,以便 API 的用户可以依赖类型检查和自动完成,而不是手动复制和粘贴字段以形成path数组。

标签: javascript

解决方案


正如评论所说:

深度克隆缓存,修改克隆,返回整个克隆

JSON.stringify使用/JSON.parse您喜欢的任何方法进行深度克隆。然后你需要一种分配给 deep 属性的方法,也许让函数接受 final 属性作为附加参数:

function filter(cache, thingsToRemove, mapper, lastProp) {
  const clonedCache = deepClone(cache);
  const lastObj = mapper(clonedCache);
  lastObj[lastProp] = lastObj[lastProp].filter(
    (thing) => !thingsToRemove.includes(thing)
  );
  return clonedCache;
}

并在作为第四个参数(cache) => cache.a.b.c传递(cache) => cache.a.b时更改对的调用。'c'


推荐阅读