按 javascript 中的路径更新嵌套对象
Updating nested object by path in javascript
假设我有这个对象:
{
categories: [
{ name: "My Category", products: [ { name: "My Product", price: 15 }] },
{ name: "Another", products: [ { name: "Movie", price: 25 }, { name: "Cartoon", price: 7.5 } ] },
{ name: "Lastly", subcategories: [
{ name: "Food", products: [ { name: "Avocado", price: 1.25} ] }
]
}
]
}
我希望能够通过如下函数调用更新此对象中的价格:
update(object, "categories/0/products/0",25)
// this would change first product in first category
这个答案Javascript: how to dynamically create nested objects using object names given by an array很好,但没有解决对象中有数组的情况。
可接受下划线。
注意:这个答案 Javascript: how to dynamically create nested objects INCLUDING ARRAYS using object names given by an array 没有删减它,因为我没有那种形式的数组引用 (products[1])
您需要根据链接的答案稍微修改函数
var object = {
categories: [
{ name: "My Category", products: [ { name: "My Product", price: 15 }] },
{ name: "Another", products: [ { name: "Movie", price: 25 }, { name: "Cartoon", price: 7.5 } ] },
{ name: "Lastly", subcategories: [
{ name: "Food", products: [ { name: "Avocado", price: 1.25} ] }
]
}
]
}
function update(obj, keyPath, value) {
keyPath = keyPath.split('/'); // split key path string
lastKeyIndex = keyPath.length-1;
for (var i = 0; i < lastKeyIndex; ++ i) {
key = keyPath[i];
// choose if nested object is array or hash based on if key is number
if (!(key in obj)) obj[key] = parseInt(key) !== parseInt(key) ? {}: []
obj = obj[key];
}
obj[keyPath[lastKeyIndex]] = value;
}
console.log(`Original price ${object.categories[0].products[0].price}`);
update(object, "categories/0/products/0/price",25)
console.log(`New price ${object.categories[0].products[0].price}`);
我这样做了,也许它能帮到你。
const updateObjectValueByPath = ({ arrayPath, data, value }) => {
const key = arrayPath[0];
if (Array.isArray(data) && data !== null) {
if (arrayPath.length > 1) {
return data.map((el, index) => {
if (index === key) {
return updateObjectValueByPath({
arrayPath: arrayPath.slice(1, arrayPath.length),
data: el,
value,
});
}
return el;
}, []);
}
return [...data, value];
}
if (typeof data === 'object' && !Array.isArray(data) && data !== null) {
if (arrayPath.length > 1) {
return {
...data,
[key]: updateObjectValueByPath({
arrayPath: arrayPath.slice(1, arrayPath.length),
data: data[key],
value,
}),
};
}
return { ...data, [key]: value };
}
return data;
};
const data = {
categories: [
{ name: "My Category", products: [ { name: "My Product", price: 15 }] },
{ name: "Another", products: [ { name: "Movie", price: 25 }, { name: "Cartoon", price: 7.5 } ] },
{ name: "Lastly", subcategories: [
{ name: "Food", products: [ { name: "Avocado", price: 1.25} ] }
]
}
]
};
const arrayPath = ['categories', 0, 'products', 0, 'price'];
const value = 25;
const newData = updateObjectValueByPath({data, value, arrayPath});
console.log({newData});
假设我有这个对象:
{
categories: [
{ name: "My Category", products: [ { name: "My Product", price: 15 }] },
{ name: "Another", products: [ { name: "Movie", price: 25 }, { name: "Cartoon", price: 7.5 } ] },
{ name: "Lastly", subcategories: [
{ name: "Food", products: [ { name: "Avocado", price: 1.25} ] }
]
}
]
}
我希望能够通过如下函数调用更新此对象中的价格:
update(object, "categories/0/products/0",25)
// this would change first product in first category
这个答案Javascript: how to dynamically create nested objects using object names given by an array很好,但没有解决对象中有数组的情况。
可接受下划线。
注意:这个答案 Javascript: how to dynamically create nested objects INCLUDING ARRAYS using object names given by an array 没有删减它,因为我没有那种形式的数组引用 (products[1])
您需要根据链接的答案稍微修改函数
var object = {
categories: [
{ name: "My Category", products: [ { name: "My Product", price: 15 }] },
{ name: "Another", products: [ { name: "Movie", price: 25 }, { name: "Cartoon", price: 7.5 } ] },
{ name: "Lastly", subcategories: [
{ name: "Food", products: [ { name: "Avocado", price: 1.25} ] }
]
}
]
}
function update(obj, keyPath, value) {
keyPath = keyPath.split('/'); // split key path string
lastKeyIndex = keyPath.length-1;
for (var i = 0; i < lastKeyIndex; ++ i) {
key = keyPath[i];
// choose if nested object is array or hash based on if key is number
if (!(key in obj)) obj[key] = parseInt(key) !== parseInt(key) ? {}: []
obj = obj[key];
}
obj[keyPath[lastKeyIndex]] = value;
}
console.log(`Original price ${object.categories[0].products[0].price}`);
update(object, "categories/0/products/0/price",25)
console.log(`New price ${object.categories[0].products[0].price}`);
我这样做了,也许它能帮到你。
const updateObjectValueByPath = ({ arrayPath, data, value }) => {
const key = arrayPath[0];
if (Array.isArray(data) && data !== null) {
if (arrayPath.length > 1) {
return data.map((el, index) => {
if (index === key) {
return updateObjectValueByPath({
arrayPath: arrayPath.slice(1, arrayPath.length),
data: el,
value,
});
}
return el;
}, []);
}
return [...data, value];
}
if (typeof data === 'object' && !Array.isArray(data) && data !== null) {
if (arrayPath.length > 1) {
return {
...data,
[key]: updateObjectValueByPath({
arrayPath: arrayPath.slice(1, arrayPath.length),
data: data[key],
value,
}),
};
}
return { ...data, [key]: value };
}
return data;
};
const data = {
categories: [
{ name: "My Category", products: [ { name: "My Product", price: 15 }] },
{ name: "Another", products: [ { name: "Movie", price: 25 }, { name: "Cartoon", price: 7.5 } ] },
{ name: "Lastly", subcategories: [
{ name: "Food", products: [ { name: "Avocado", price: 1.25} ] }
]
}
]
};
const arrayPath = ['categories', 0, 'products', 0, 'price'];
const value = 25;
const newData = updateObjectValueByPath({data, value, arrayPath});
console.log({newData});