javascript - 遍历返回空值的大对象
问题描述
我从互联网上复制了一个代码,它在其中搜索一个 json 集合 - 找到相关的键并根据操作返回它们的值,无论是整体还是单个数组。问题是它只搜索它找到的值并总结它们。我想要一个附加功能来查找哪个键具有空值。请如果有人可以调查一下。
function perform(keys, operation) {
function visit(object) {
Object.entries(object).forEach(([k, v]) => {
if (k in indices) return fn(result, indices[k], v);
if (v && typeof v === "object") visit(v);
});
}
var result = [],
indices = Object.assign({}, ...keys.map((k, i) => ({ [k]: i }))),
fn = {
notsum: function(target, key, value) {
if (target[key] === undefined) {
target[key] = value;
return;
}
if (!Array.isArray(target[key])) {
target[key] = [target[key]];
}
target[key].push(value);
},
sum: function(target, key, value) {
target[key] = (target[key] || 0) + value;
}
}[operation === "total" ? "sum" : operation];
visit(data);
//to add functionality here to get the keys with values, even if they are null
//end
return operation === "total" ? result.reduce((a, b) => a + b) : result;
}
这个怎么运作
console.log(perform(["WA1", "WA3", "RAE1"], "notsum")); // [3, 2, 1]
console.log(perform(["WA1", "WA3", "RAE1"], "total")); // 6
JSON 对象可以简单也可以复杂
var data = {
version: "1.0",
submission: "editing",
WebData: {
WA1: 3,
WA3: 2,
WAX: "NEO",
WebGroup: [{ Web1: 3, Web2: 0 }, { Web1: 4, Web2: 1 }]
},
NonWebData: { NWA1: 3, NWA2: "INP", NWA3: 2 },
FormInputs: { FM11: 3, FM12: 1, FM13: 2 },
RawData: {
RawOverview: { RAE1: 1, RAE2: 1 },
RawGroups: [
{
name: "A1",
id: "1",
data: {
AD1: "period",
AD2: 2,
AD3: 2,
transfers: [
{ type: "in", TT1: 1, TT2: 2 },
{ type: "out", TT1: 1, TT2: 2 }
]
}
},
{
name: "A2",
id: "2",
data: {
AD1: "period",
AD2: 2,
AD3: 2,
transfers: [
{ type: "in", TT1: 1, TT2: 2 },
{ type: "out", TT1: 1, TT2: 2 }
]
}
}
]
},
Other: { O1: 1, O2: 2, O3: "hello" },
AddedBy: "name",
AddedDate: "11/02/2019"
};
该功能确实返回索引,我拥有所有键,但我想要键值对,所以我知道数组中的哪一个根本不存在。写在函数中的代码给我
["WA1", "WA3", "RAE1"]
[2, null, null]
现在,它只查找该值是否存在,并将它们相加并给我 2 作为结果。
提前谢谢了
解决方案
您可以编写一个函数,递归访问对象树中的所有节点并执行您想要的操作。下面是一个示例函数,它sum
和“getBykey”。
function perform(obj, keys = [], operation = "getByKey") {
const results = [];
let sum = 0;
// Define a fucntion that traverses all nodes in your object tree
const visit = (obj, keys = [], operation = "getByKey") => {
if (obj && typeof obj === "object") {
Object.entries(obj).forEach(([key, value]) => {
if (keys.includes(key)) {
// You can add more if_block/switch_case for more operations
if (operation === "sum" && !isNaN(value)) {
sum += value;
} else {
results.push({ [key]: value });
}
}
visit(value, keys, operation);
});
}
}
// Traverse the object tree
visit(obj, keys, operation);
return operation === "sum" ? sum : results;
}
const getByKey = perform(data, ["WA1", "WA3", "RAE1", "AD1"]);
const sum = perform(data, ["WA1", "WA3", "RAE1"], 'sum');
console.log(sum);
console.log(getByKey);