遍历嵌套对象时修改对象键

时间:2020-01-17 09:48:59

标签: javascript typescript object ecmascript-6

我想遍历嵌套对象并修改每个键(删除第一个字符)。

以下代码遍历整个对象,但不修改密钥。运行该功能后,对象仍然看起来相同。

const removeFirstCharacterOfKey = (obj) => {
    Object.keys(obj).forEach((key) => {
        if (typeof obj[key] === 'object') {
            if(Array.isArray(obj[key])) {
                return;
            }
            return removeFirstCharacterOfKey (obj[key]);
        }
        key = key.substring(1);
    });
}

也可能是使用修改后的键创建新对象。有可能做到这一点吗?

2 个答案:

答案 0 :(得分:2)

https://codesandbox.io/embed/cool-golick-vdf6k?fontsize=14&hidenavigation=1&previewwindow=tests&theme=dark

array.reduce是您最好的选择。您的情况下的基本实施方式是

function serializer(obj) {
  return Object.entries(obj).reduce((obj, [key, entry]) => ({
      ...obj,
      [key.substr(1)]: entry
    }),{});
}

但是您需要对数组进行其他检查,因此我们需要修改方法以接受自定义修饰符

function serializer(obj, modifier) {
  return Object.entries(obj).reduce(
    (obj, [key, entry]) => ({
      ...obj,
      [modifier(key, entry)]: entry
    }),
    {}
  );
}

并将其用作

const myObj = {
  $a: "hello a",
  $b: "hello b",
  $c: [],
  $d: "hello d",
  $e: "hello e"
};

function serializer(obj, modifier) {
  return Object.entries(obj).reduce(
    (obj, [key, entry]) => ({
      ...obj,
      [modifier(key, entry)]: entry
    }),
    {}
  );
}

const serialized = serializer(myObj, (key, entry) =>
  Array.isArray(entry) ? key : key.substr(1)
);

test("", () => {
  expect(serialized).toEqual({
    a: "hello a",
    b: "hello b",
    $c: [],
    d: "hello d",
    e: "hello e"
  });
});

答案 1 :(得分:1)

在当前代码中,您永远不会突变现有对象(或创建新对象),而只是重新分配key参数,不会产生任何副作用。

考虑使用递归Object.fromEntries映射函数:

const obj = {
  foo: {
    bar: 'val',
    baz: {
      buzz: 'val',
      buzz2: 'val'
    }
  }
};

const objWithSlicedKeys = obj => Object.fromEntries(
  Object.entries(obj).map(
    ([key, val]) => [
      key.slice(1),
      typeof val === 'object' && val !== null ? objWithSlicedKeys(val) : val
    ]
  )
);
console.log(objWithSlicedKeys(obj));

相关问题