[英]Find and update in nested json object
我使用此代碼從sJhonny's Question的 json 對象中找到所需的部分
數據樣本
TestObj = {
"Categories": [{
"Products": [{
"id": "a01",
"name": "Pine",
"description": "Short description of pine."
},
{
"id": "a02",
"name": "Birch",
"description": "Short description of birch."
},
{
"id": "a03",
"name": "Poplar",
"description": "Short description of poplar."
}],
"id": "A",
"title": "Cheap",
"description": "Short description of category A."
},
{
"Product": [{
"id": "b01",
"name": "Maple",
"description": "Short description of maple."
},
{
"id": "b02",
"name": "Oak",
"description": "Short description of oak."
},
{
"id": "b03",
"name": "Bamboo",
"description": "Short description of bamboo."
}],
"id": "B",
"title": "Moderate",
"description": "Short description of category B."
}]
};
查找功能
function getObjects(obj, key, val) {
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
objects = objects.concat(getObjects(obj[i], key, val));
} else if (i == key && obj[key] == val) {
objects.push(obj);
}
}
return objects;
}
像這樣使用:
getObjects(TestObj, 'id', 'A'); // Returns an array of matching objects
此代碼用於從源中選擇匹配的片段。 但我想要的是用新值更新源對象並檢索更新的源對象。
我想要類似的東西
getObjects(TestObj, 'id', 'A', 'B'); // Returns source with updated value. (ie id:'A' updated to id:'B' in the returned object)
我的代碼
function getObjects(obj, key, val, newVal) {
var newValue = newVal;
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
objects = objects.concat(getObjects(obj[i], key, val));
} else if (i == key && obj[key] == val) {
obj[key] = 'qwe';
}
}
return obj;
}
如果我給obj[key] = 'qwe';
這會起作用obj[key] = 'qwe';
但如果我將代碼更改為obj[key] = newValue;
其更新為未定義。
為什么?
您忘記在嵌套調用中傳遞 newValue
function getObjects(obj, key, val, newVal) {
var newValue = newVal;
var objects = [];
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
objects = objects.concat(getObjects(obj[i], key, val, newValue));
} else if (i == key && obj[key] == val) {
obj[key] = 'qwe';
}
}
return obj;
}
function getObjects(obj, key, val, newVal) {
for (var i in obj) {
if (!obj.hasOwnProperty(i)) continue;
if (i == key && obj[key] == val) {
obj[key] = newVal;
}
}
return obj
}
這將使用 newValue (newVal) 對找到的值進行就地更新
這 ?
function update(obj, key, newVal) {
for(var i in obj) {
if(typeof obj[i] == 'object') {
update(obj[i], key, newVal));
} else if(i === key) {
obj[i] = newVal;
}
}
return obj;
}
你可以試試我的解決方案
const InsertOrUpdate = (dest, src) => {
GetValue(dest, src, [])
}
const GetValue = (dest, src, keys) => {
for (let key in src) {
let srcValue = src[key]
// Don't use push here
// The concat() method does not change the existing arrays, but returns a new array, containing the values of the joined arrays
let parentKeys = keys.concat(key)
if (typeof (srcValue) === 'object') {
GetValue(dest, srcValue, parentKeys)
} else {
SetValue(dest, parentKeys, srcValue)
}
}
}
const SetValue = (dest, keys, value) => {
if (!keys.length || keys.length === 0) {
return
}
let key = keys[0]
let childKeys = keys.slice(1)
// update
// note: null is object
if (dest[key] && typeof (dest[key]) === 'object') {
SetValue(dest[key], childKeys, value)
} else {
// insert
if (childKeys.length === 0) {
dest[key] = value
} else {
// insert parent key & continue update
dest[key] = {}
SetValue(dest[key], childKeys, value)
}
}
}
我嘗試使用上面選擇的解決方案,但它會用相同的值更新每一行。 因此,我添加了一種方法來定義您要更新的記錄,以及一種在您循環過去后跟蹤當前記錄 ID 的方法。
function getObjects(obj, rowId, key, val, newVal, rId) {
var objects = [];
for (var i in obj) {
if(obj[i].id !== undefined) rId = obj[i].id;
if (!obj.hasOwnProperty(i)) continue;
if (typeof obj[i] == 'object') {
objects = objects.concat(this.updateObject(obj[i], rowId, key, val, newVal, rId));
} else if (i == key && obj[key] == val) {
if(rId == rowId) obj[key] = newVal;
}
}
return obj;
}
看看對象掃描。 我們現在使用它進行大量數據處理。 對我們來說,它使代碼更易於維護,只需花一點時間來了解它。 這是你如何回答你的問題
// const objectScan = require('object-scan'); const update = (data, needle, from, to) => objectScan([needle], { abort: true, rtn: 'bool', filterFn: ({ value, parent, property }) => { if (value === from) { parent[property] = to; return true; } return false; } })(data); // ------------------------------- const TestObj = { Categories: [{ Products: [{ id: 'a01', name: 'Pine', description: 'Short description of pine.' }, { id: 'a02', name: 'Birch', description: 'Short description of birch.' }, { id: 'a03', name: 'Poplar', description: 'Short description of poplar.' }], id: 'A', title: 'Cheap', description: 'Short description of category A.' }, { Product: [{ id: 'b01', name: 'Maple', description: 'Short description of maple.' }, { id: 'b02', name: 'Oak', description: 'Short description of oak.' }, { id: 'b03', name: 'Bamboo', description: 'Short description of bamboo.' }], id: 'B', title: 'Moderate', description: 'Short description of category B.' }] }; console.log(update(TestObj, '**.id', 'A', 'B')); // => true console.log(TestObj); // => { Categories: [ { Products: [ { id: 'a01', name: 'Pine', description: 'Short description of pine.' }, { id: 'a02', name: 'Birch', description: 'Short description of birch.' }, { id: 'a03', name: 'Poplar', description: 'Short description of poplar.' } ], id: 'B', title: 'Cheap', description: 'Short description of category A.' }, { Product: [ { id: 'b01', name: 'Maple', description: 'Short description of maple.' }, { id: 'b02', name: 'Oak', description: 'Short description of oak.' }, { id: 'b03', name: 'Bamboo', description: 'Short description of bamboo.' } ], id: 'B', title: 'Moderate', description: 'Short description of category B.' } ] }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/object-scan@13.8.0"></script>
免責聲明:我是對象掃描的作者
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.