Глубокая замена значения, зная значение атрибута внутри объекта, мы должны ввести значение в - PullRequest
1 голос
/ 13 марта 2019

У нас есть глубоко вложенная структура, которая меняется каждый раз, когда мы запускаем приложение.

{
  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, но, поскольку мы не можем знать, где именно находится значение, которое мы должны ввести, и мы знаем только значение ключа, в который мы должны ввести значение, нам не удалось получить это работает.

Ответы [ 3 ]

1 голос
/ 13 марта 2019

Вы можете выполнить рекурсивный поиск и заменить ...

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)
1 голос
/ 13 марта 2019

Имейте рекурсивную функцию, проходящую через объект и изменяющую его в зависимости от значения того, что вы ищете.

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);
1 голос
/ 13 марта 2019

Решением может быть использование рекурсивной функции, подобной этой:

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);
...