javascript - Function to update any value by key in nested object - Stack Overflow

I want to write a function that takes a keyName, newValue, and object, and returns the object with the

I want to write a function that takes a keyName, newValue, and object, and returns the object with the updated key/value pair. For example...

Given this data:

const data = {
  token: {
    id: "abcxyz",
    year: "2022"
  },
  order_data: {
    customer: "Jane",
    shipping: {
      country: "US",
      state: "TX"
    }
  }
}

and a function with these arguments:

const updateObject = (keyName, newValue, object) => {
...
}

I want to be able to call:

const newObject = updateObject("customer", "Bob", data);

so that

newObject = {
      token: {
        id: "abcxyz",
        year: "2022"
      },
      order_data: {
        customer: "Bob",
        shipping: {
          country: "US",
          state: "TX"
        }
      }
    }

My current wrong attempt looks like this:

const updateObject = (keyName, newVal, object) => {
  const results = {};
  for (var key in object) {
    if (key === keyName) {
      results = {
        ...object,
        keyName: newVal
      };
    } else {
      results[key] = object[key];
      if (typeof object[key] === "object") {
        updateObject(keyName, newVal, object.key);
      }
    }
  }
  return results
};

I've been digging through posts on recursion and spread operators all day but can't quite get it right. The nested object can be any shape and depth which is throwing me off.

I want to write a function that takes a keyName, newValue, and object, and returns the object with the updated key/value pair. For example...

Given this data:

const data = {
  token: {
    id: "abcxyz",
    year: "2022"
  },
  order_data: {
    customer: "Jane",
    shipping: {
      country: "US",
      state: "TX"
    }
  }
}

and a function with these arguments:

const updateObject = (keyName, newValue, object) => {
...
}

I want to be able to call:

const newObject = updateObject("customer", "Bob", data);

so that

newObject = {
      token: {
        id: "abcxyz",
        year: "2022"
      },
      order_data: {
        customer: "Bob",
        shipping: {
          country: "US",
          state: "TX"
        }
      }
    }

My current wrong attempt looks like this:

const updateObject = (keyName, newVal, object) => {
  const results = {};
  for (var key in object) {
    if (key === keyName) {
      results = {
        ...object,
        keyName: newVal
      };
    } else {
      results[key] = object[key];
      if (typeof object[key] === "object") {
        updateObject(keyName, newVal, object.key);
      }
    }
  }
  return results
};

I've been digging through posts on recursion and spread operators all day but can't quite get it right. The nested object can be any shape and depth which is throwing me off.

Share Improve this question asked Jul 21, 2022 at 19:39 JBrownJBrown 9391 gold badge9 silver badges27 bronze badges 4
  • 1 What happens if there are two properties named customer? – James Curran Commented Jul 21, 2022 at 19:41
  • @JamesCurran you can assume that there will not be two properties with the same key – JBrown Commented Jul 21, 2022 at 19:45
  • youmightnotneed./lodash#set – cmgchess Commented Jul 21, 2022 at 19:49
  • @cmgchess you need to specify the path for that method. Is there a way to acplish the same thing but using the three arguments I specified above? – JBrown Commented Jul 21, 2022 at 19:52
Add a ment  | 

4 Answers 4

Reset to default 5

The spread syntax in your function isn't necessary (you already create a new object with results = {}), and keyname creates a .keyname property not one with a dynamic name (same problem in using object.key instead of object[key] - you might want to revisit dot vs bracket notation). But the main problem is that your updateObject function doesn't update the object it was passed, rather it returns a new one - and you need to consider that in your recursive call. So it should be

function updateObject(keyName, newVal, object) {
  const results = {};
  for (var key in object) {
    if (key === keyName) {
      results[key] = newVal;
    } else if (typeof object[key] === "object" && object[key] !== null) {
      results[key] = updateObject(keyName, newVal, object[key]);
    } else {
      results[key] = object[key];
    }
  }
  return results;
}

Its pretty simple. We just loop through and find the key and then update the value. if its not found we call the function again. Most important is to return the updated value at the end of the function

This line var newData = JSON.parse(JSON.stringify(data)); is just so that we dont edit the original object as you requested

var data = {
  token: {
    id: "abcxyz",
    year: "2022"
  },
  order_data: {
    customer: "Bob",
    shipping: {
      country: "US",
      state: "TX"
    }
  }
}

const updateObject = (keyName, newVal, object) => {
  for (var key in object) {
    if (key === keyName) {
      object[key] = newVal;
    } else {
      if(typeof object[key] === "object"){
        object[key] = updateObject(keyName, newVal, object[key]);
      }
    }
  }
  return object;
};

var newData = JSON.parse(JSON.stringify(data));
updateObject("customer", "Test", newData);
console.log(data);
console.log(newData);

If you're looking for an approach that doesn't mutate your original (and really now, who wouldn't be?

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744142516a4560269.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信