admin管理员组文章数量:1279008
I've got a collection of disparate, plex JSON objects from a CouchDB database. Each contains many levels of nested properties--for example,
tps_report.personnel_info.productivity.units_sold = 8
I want to iterate through these objects and do stuff with them: for instance,
// writes units sold from each TPS report:
for (i in tpsReports) {
if (tpsReports[i].personnel_info.productivity.units_sold < 10) {
fireEmployee();
}
}
The problem is that many TPS reports don't have all these properties set. So if I try this, I'll get an error the first time the loop gets to a report without the "personnel_info" property and thus tries to find the "productivity" property of "undefined." What I'd rather happen is that the conditional just skips it and continues.
I see two ways around this, both of which seem ugly to me
- test for each property separately with nested conditionals
- enclose the line in a try/catch block to catch the error and ignore it
What I'd prefer would be something like PHP's isset() function, which won't throw an error regardless of what you feed it--it'll just tell you whether the particular variable you're looking for exists or not. So, like
// writes units sold from each TPS report:
for (i in tpsReports) {
if (isset(tpsReports[i].personnel_info.productivity.units_sold)){
if (tpsReports[i].personnel_info.productivity.units_sold < 10) {
fireEmployee();
}
}
}
Any thoughts?
I've got a collection of disparate, plex JSON objects from a CouchDB database. Each contains many levels of nested properties--for example,
tps_report.personnel_info.productivity.units_sold = 8
I want to iterate through these objects and do stuff with them: for instance,
// writes units sold from each TPS report:
for (i in tpsReports) {
if (tpsReports[i].personnel_info.productivity.units_sold < 10) {
fireEmployee();
}
}
The problem is that many TPS reports don't have all these properties set. So if I try this, I'll get an error the first time the loop gets to a report without the "personnel_info" property and thus tries to find the "productivity" property of "undefined." What I'd rather happen is that the conditional just skips it and continues.
I see two ways around this, both of which seem ugly to me
- test for each property separately with nested conditionals
- enclose the line in a try/catch block to catch the error and ignore it
What I'd prefer would be something like PHP's isset() function, which won't throw an error regardless of what you feed it--it'll just tell you whether the particular variable you're looking for exists or not. So, like
// writes units sold from each TPS report:
for (i in tpsReports) {
if (isset(tpsReports[i].personnel_info.productivity.units_sold)){
if (tpsReports[i].personnel_info.productivity.units_sold < 10) {
fireEmployee();
}
}
}
Any thoughts?
Share Improve this question asked Dec 3, 2010 at 6:26 thisismynamethisismyname 5432 gold badges5 silver badges10 bronze badges 1- Refer this link for answer stackoverflow./questions/2281633/javascript-isset-equivalent/… – bikash.bilz Commented Jul 4, 2019 at 12:10
6 Answers
Reset to default 5function isset(obj, propStr) {
var parts = propStr.split(".");
var cur = obj;
for (var i=0; i<parts.length; i++) {
if (!cur[parts[i]])
return false;
cur = cur[parts[i]];
}
return true;
}
Note that the second parameter is a string, so the exception doesn't get thrown when accessing a property on a nonexistent property.
Theres a function defined on this blog to safely read nested properties from a JS object
It allows you to mine an object for properties... ie.
safeRead(tps_report, 'personnel_info', 'productivity', 'units_sold');
and if any part of the object chain is null or undefined it returns an empty string....
/**
* units sold from each TPS report
*/
var units;
// the hard way
units = (report && report.personnel && report.personnel.info &&
report.personnel.info.sales && report.personnel.info.sales.units &&
report.personnel.info.sales.units.sold) || 0;
// the easy way
units = selectn('personnel.info.sales.units.sold', report) || 0;
// resulting action
if (units < 10) fireEmployee();
Shameless plug: I am the author of selectn. It is avaialble via npm install selectn
or bower install selectn
or ponent install wilmoore/selectn
.
Check out the examples on the readme to find out why this is better than an isset
clone. You can also use it as a filter predicate so you can scrub out nested objects that do not contain a particular deeply nested property.
You can use my ObjectPath to query big nested JSON documents. The cause I'm building it is the lack of good tools in programming languages to work with JSON just as mentioned in the question.
The project is open sourced and under AGPL license.
http://adriank.github.io/ObjectPath/
Javascript implementation is not optimized and lacks half of the Python's functionality but I'm keen to add new things if needed by munity - just ping me about what is crucial to you.
I really like the elegance of jsonpath, an equivalent to xpath, but for json.
http://goessner/articles/JsonPath/
There you can do an expression like:
var units_sold = jsonPath(tpsResports, '$.[*].personnel_info.productivity.units_sold');
// units_sold is array of found values...
(I didn't double check my expression, it may be wrong for what you want in your example)
The ugly way :
for (i in tpsReports) {
try {
if(tpsReports[i].personnel_info.productivity.units_sold < 10) {
fireEmployee();
}
} catch (e) {}
}
本文标签: In JavaScripttest for property deeply nested in object graphStack Overflow
版权声明:本文标题:In javascript, test for property deeply nested in object graph? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741301200a2371098.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论