代码之家  ›  专栏  ›  技术社区  ›  Vikhyath Maiya

递归替换所有对象值

  •  5
  • Vikhyath Maiya  · 技术社区  · 8 年前

    我在我的一个项目中使用angular 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 回复  |  直到 8 年前
        1
  •  7
  •   brk    8 年前

    希望你能试试这样的东西。

    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))
        2
  •  1
  •   Omkar Rajam    6 年前

    答复人 @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将仅更改其至少一个字段已更改的对象的引用。这将是一个有用的优化。对于此方法,我们应该使用 changeValue 提供人: @brk(刹车) .Immer将识别突变并更改必要的参考。

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