JavaScript对象相当于JSON.stringify的replace函数

huangapple go评论57阅读模式
英文:

Javascript Object equivilent of JSON.stringify's replace function

问题

如果我有一个对象

const data = { a: 'a', b: 'b', c: { hello: 'hello'} }

而且我想在上面运行一个(深度的)替换函数,就像JSON.stringify提供的那个:

const stringData = JSON.stringify(data, (k, v) => {
    if (k === 'hello') {
        return 'hello world!';
    }
    return v;
})
//{"a":"a","b":"b","c":{"hello":"hello world!"}}

但实际上不对该对象进行字符串化。最简单的方法是什么(不使用任何外部库,实际实现替换函数,而且不进行字符串化和解析)?

谢谢

英文:

Say I have an object

const data = { a: 'a', b: 'b', c: { hello: 'hello'} }

And I'd like to run a (deep) replacer function on that, like the one supplied with JSON.stringify:

const stringData = JSON.stringify(data, (k, v) => {
    if (k === 'hello') {
     return 'hello world!';
    }
    return v;
})
//{"a":"a","b":"b","c":{"hello":"hello world!"}}

But without actually strigifying that object. What would be the easiest way to do so (without any external library, actual implementation of a replacement function and without stingifying-parsing)?

Thanks

答案1

得分: 2

已经有一个使用 @VasimHayat 提供的递归函数的答案,是正确的。但由于主要关注使用 replacer 函数,也可以使用以下变体:

const object = {
  a: "a",
  b: "b",
  c: "c",
  d: "d",
  h: {
    hello: "hello",
  },
};

function replacer(obj, key) {
  if (typeof key === "string" && key === "hello") {
    return "hello world";
  }

  return obj[key];
}

function traverse(obj, replacer) {
  const keys = Object.keys(obj);
  for (const key of keys) {
    if (typeof obj[key] === "object" && obj[key].length) {
      // array
      obj[key] = replacer(obj, key);
    } else if (typeof obj[key] === "object") {
      // object
      obj[key] = traverse(obj[key], replacer);
    } else {
      // primitive
      obj[key] = replacer(obj, key);
    }
  }

  return obj;
}

(() => {
  traverse(object, replacer);
  console.log("Object", object);
})();

请注意,无法检测循环引用,如果对象具有循环引用,这种方法将无法正常工作。

英文:

There is already an answer on using a recursive function by @VasimHayat above which is correct. But since the main focus was on using a replacer function, the following variation can be used as well:

const object = {
  a: "a",
  b: "b",
  c: "c",
  d: "d",
  h: {
    hello: "hello",
  },
};

function replacer(obj, key) {
  if (typeof key === "string" && key === "hello") {
    return "hello world";
  }

  return obj[key];
}

function traverse(obj, replacer) {
  const keys = Object.keys(obj);
  for (const key of keys) {
    if (typeof obj[key] === "object" && obj[key].length) {
      // array
      obj[key] = replacer(obj, key);
    } else if (typeof obj[key] === "object") {
      // object
      obj[key] = traverse(obj[key], replacer);
    } else {
      // primitive
      obj[key] = replacer(obj, key);
    }
  }

  return obj;
}

(() => {
  traverse(object, replacer);
  console.log("Object", object);
})();

Note that there are no ways of detecting cycles and if the object has cyclical references this will not work.

huangapple
  • 本文由 发表于 2023年3月15日 21:28:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/75745372.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定