在知道对象内属性值的值的情况下深度替换值,我们必须在

时间:2019-03-13 16:09:23

标签: javascript lodash

我们有一个深层嵌套的结构,每次运行该应用程序时都会发生变化。

{
  some: {
    complex: {
      unknown: {
        structure: {
          fields: [
            { name: "group1", other: "data", currentValue: "" },
            { name: "group2", other: "another data", currentValue: "" },
          ]
        }
      }
    }
  }
}

我们必须在这种结构中注入适当的值。例如,我们收到

{ 
  group1: 'the proper value'
}

我们必须替换适当组中的值以获得:

{
  some: {
    complex: {
      unknown: {
        structure: {
          fields: [
            { name: "group1", other: "data", currentValue: "the proper value" },
            { name: "group2", other: "another data", currentValue: "" },
          ]
        }
      }
    }
  }
}

我们尝试使用lodash mergeWith,但是由于我们无法确切知道必须在哪里注入值,而且我们只知道必须在其中注入值的对象键的of值,因此我们无法获得这个工作。

3 个答案:

答案 0 :(得分:1)

一种解决方案可能是使用这样的递归函数:

object={
  some: {
    complex: {
      unknown: {
        structure: {
          fields: [
            { name: "group1", other: "data", currentValue: "" },
            { name: "group2", other: "another data", currentValue: "" },
          ]
        }
      }
    }
  }
};
newValue={ 
  group1: 'the proper value'
};
var inserted=false;
function search(data, newData){
    if(inserted) return;
    for(key in data){
         if(data[key]==Object.keys(newData)[0]){
              data["currentValue"]=newData[Object.keys(newData)[0]];
              inserted=true;
              return;
         }else
              search(data[key], newData);
    }
}   
search(object, newValue);
console.log(object);

答案 1 :(得分:1)

您可以进行递归搜索并替换...

let theObj = {
  some: {
    complex: {
      unknown: {
        structure: {
          fields: [
            { name: "group1", other: "data", currentValue: "" },
            { name: "group2", other: "another data", currentValue: "" },
          ]
        }
      }
    }
  }
}

function updateObj(obj, replacement) {
  if(Array.isArray(obj)) {
      let key = Object.keys(replacement)[0]
      let itm = obj.find(i => i.name == key)
      itm.data = replacement[key]
  } else if(typeof obj == 'object') {
    for(let i in obj) {
      updateObj(obj[i], replacement)
    }
  }
}


updateObj(theObj, { group1: 'the proper value' })
console.log(theObj)

答案 2 :(得分:1)

具有一个递归函数,该递归函数遍历对象并根据所寻找的值对其进行变异。

const obj = {
  some: {
    complex: {
      unknown: {
        structure: {
          fields: [{
              name: 'group1',
              other: 'data',
              currentValue: '',
            },
            {
              name: 'group2',
              other: 'another data',
              currentValue: '',
            },
          ],
        },
      },
    },
  },
};

const toChange = {
  group1: 'the proper value',
  group2: 'the proper value 2',
};

// Recursive function that go replace
function lookAndReplace(config, ptr) {
  // If we deal with an object look at it's keys
  if (typeof ptr === 'object') {
    Object.keys(ptr).forEach((x) => {
      // If the keys is the one we was looking for check the value behind
      if (x === config.keyToCheck) {
        // We have found one occurence of what we wanted to replace
        // replace the value and leave
        if (ptr[x] === config.key) {
          ptr[config.keyToReplace] = config.value;
        }

        return;
      }

      // Go see into the value behind the key for our data
      lookAndReplace(config, ptr[x]);
    });
  }

  // If we are dealing with an array, look for the keys
  // inside each of the elements
  if (ptr instanceof Array) {
    ptr.forEach(x => lookAndReplace(config, x));
  }
}

// For each group we look for, go and replace
Object.keys(toChange).forEach(x => lookAndReplace({
  key: x,
  value: toChange[x],
  keyToCheck: 'name',
  keyToReplace: 'currentValue',
}, obj));

console.log(obj);


/!\重要的是,这种解决方案也适用于嵌套数组

const obj = {
  some: {
    complex: {
      unknown: {
        structure: {
          // fields is an array of array
          fields: [
            [{
              name: 'group1',
              other: 'data',
              currentValue: '',
            }],
            [{
              name: 'group2',
              other: 'another data',
              currentValue: '',
            }],
          ],
        },
      },
    },
  },
};

const toChange = {
  group1: 'the proper value',
  group2: 'the proper value 2',
};

// Recursive function that go replace
function lookAndReplace(config, ptr) {
  // If we deal with an object look at it's keys
  if (typeof ptr === 'object') {
    Object.keys(ptr).forEach((x) => {
      // If the keys is the one we was looking for check the value behind
      if (x === config.keyToCheck) {
        // We have found one occurence of what we wanted to replace
        // replace the value and leave
        if (ptr[x] === config.key) {
          ptr[config.keyToReplace] = config.value;
        }

        return;
      }

      // Go see into the value behind the key for our data
      lookAndReplace(config, ptr[x]);
    });
  }

  // If we are dealing with an array, look for the keys
  // inside each of the elements
  if (ptr instanceof Array) {
    ptr.forEach(x => lookAndReplace(config, x));
  }
}

// For each group we look for, go and replace
Object.keys(toChange).forEach(x => lookAndReplace({
  key: x,
  value: toChange[x],
  keyToCheck: 'name',
  keyToReplace: 'currentValue',
}, obj));

console.log(obj);


const obj = {
  some: {
    complex: {
      unknown: {
        structure: {
          fields: [{
              name: "group1",
              other: "data",
              currentValue: ""
            },
            {
              name: "group2",
              other: "another data",
              currentValue: ""
            },
          ]
        }
      }
    }
  }
};

const toChange = {
  group1: 'the proper value',
  group2: 'the proper value 2',
};

// Recursive function that go replace
function lookAndReplace({
  key,
  value,
  keyToCheck,
  keyToReplace,
}, ptr) {
  // If we deal with an object
  if (typeof ptr === 'object') {
    Object.keys(ptr).forEach((x) => {
      if (x === keyToCheck) {
        // We have found one
        if (ptr[x] === key) {
          ptr[keyToReplace] = value;
        }
      } else {
        lookAndReplace({
          key,
          value,
          keyToCheck,
          keyToReplace,
        }, ptr[x]);
      }
    });
  }

  if (ptr instanceof Array) {
    ptr.forEach(x => lookAndReplace({
      key,
      value,
      keyToCheck,
      keyToReplace,
    }, x));
  }
}

// For each group we look for, go and replace
Object.keys(toChange).forEach(x => lookAndReplace({
  key: x,
  value: toChange[x],
  keyToCheck: 'name',
  keyToReplace: 'currentValue',
}, obj));

console.log(obj);