递归替换所有对象值

时间:2018-04-22 04:26:01

标签: javascript

我在我的一个项目中使用角度4,我处于需要用{{数据}}替换所有{数据}的情况。即如果我有这样的对象

{
    key: {
             key1: {
                       key2: "This is data {someData}",
                       key3: "This is data2 {someData2}"
                   }
         },
    key2: "This is data3 {someData3}"
}

结果应该是

{
    key: {
             key1: {
                       key2: "This is data {{someData}}",
                       key3: "This is data2 {{someData2}}"
                   }
         },
    key2: "This is data3 {{someData3}}"
}

我对递归和它的工作方式不太满意。所以我无法展示我尝试过的任何东西。请帮忙。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:4)

希望你能尝试这样的事情。



var orgObj = {
  key: {
    key1: {
      key2: "This is data {someData}",
      key3: "This is data2 {someData2}"
    }
  },
  key2: "This is data3 {someData3}"
}

function changeValue(obj) {
  if (typeof obj === 'object') {
    // iterating over the object using for..in
    for (var keys in obj) {
      //checking if the current value is an object itself
      if (typeof obj[keys] === 'object') {
        // if so then again calling the same function
        changeValue(obj[keys])
      } else {
        // else getting the value and replacing single { with {{ and so on
        let keyValue = obj[keys].replace('{', '{{').replace('}', '}}');
        obj[keys] = keyValue;
      }
    }
  }
  return obj;
}
console.log(changeValue(orgObj))




答案 1 :(得分:0)

@brk回答是好的,但它会使输入对象发生变异。如果某人正在使用React之类的库,在该库中请勿更改道具很重要,那么我们将不得不做一些其他事情。我们可以为在递归遍历期间找到的所有对象创建新引用。为此,我们必须注意null的值,因为typeof null也是object

//typeof null is also object. But we cannot destructure it. So check that object is not null
const isValidObject = (obj) => typeof obj === 'object' && obj !== null

function changeValue(objFromProp) {
    let obj = objFromProp;

    if (isValidObject(objFromProp)) {
        //desctructure the object to create new reference
        obj = { ...objFromProp }
        // iterating over the object using for..in
        for (var keys in obj) {
            //checking if the current value is an object itself
            if (isValidObject(obj[keys])) {
                // if so then again calling the same function
                obj[keys] = changeValue(obj[keys])
            } else {
                // else getting the value and replacing single { with {{ and so on
                let keyValue = obj[keys].replace('{', '{{').replace('}', '}}');
                obj[keys] = keyValue;
            }
        }
    }
    return obj;
}

或者,如果我们有条件地替换值,并且如果对象中的任何值都未更改,而我们想保留对象的引用,那么我们可以使用另一个库,例如immer。 Immer仅更改至少更改了一个字段的那些对象的引用。这将是有用的优化。对于这种方法,我们应该使用@brk提供的changeValue的版本。 Immer将识别突变并更改必要的参考。

import { produce } from 'immer';
const nextState = produce(objFromProp, draftState => {
    changeValue(draftState)
})