Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Ben Bacarisse Newsgroups: comp.lang.javascript Subject: Re: traverse a complex object and find value Date: Thu, 12 Jan 2017 12:42:38 +0000 Organization: A noiseless patient Spider Lines: 87 Message-ID: <877f60sb41.fsf@bsb.me.uk> References: Mime-Version: 1.0 Content-Type: text/plain Injection-Info: mx02.eternal-september.org; posting-host="4947f6d2bad1190818dcbbecb922bfa8"; logging-data="4731"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+XhBJHvjL/ECKQ4OTDduNqRM2T94HzoAU=" Cancel-Lock: sha1:GJ70cCaqEn61yzQr8m2SlN/oOLc= sha1:CcZKAL/wy8bW66tvQzZcfbn7vIc= X-BSB-Auth: 1.de5387517349c5dcea6a.20170112124238GMT.877f60sb41.fsf@bsb.me.uk Xref: csiph.com comp.lang.javascript:32172 jykl608@gmail.com writes: > I've been playing around with open weather API > (https://openweathermap.org/). After calling one of their API, i get > the following object: > { > "coord": { > "lon": -123.12, > "lat": 49.25 > }, > "weather": [ > { > "id": 800, > "main": "Clear", > "description": "clear sky", > "icon": "01d" > } > ], > "id": 6173331, > "name": "Vancouver", > "cod": 200 > } > > I want to find the value of "temp" inside the "main" property, but I > am not sure how. result.main.temp > I have written the following recursive function: > > // START hasOwnPropertyDeep(obj, prop) ======================= > > function hasOwnPropertyDeep(obj, prop) > { > if(obj.hasOwnProperty(prop)) > { > // CODE SHOULD END HERE > // BUT SOMEHOW IT GOES ALL THE WAY DOWN > // AND RETURNS FALSE > return obj[prop]; > } > > for(let p in obj) > { > let o = obj[p]; > > if( typeof(o) === "object" && o) > { > hasOwnPropertyDeep(o, prop); > } > } > > return false; > } > > // END hasOwnPropertyDeep(obj, prop) ========================= > > The above works only with the "shallow" properties. It returns the > property values deeper in the object, but it doesnt stop at the return > statement. Instead it cascades until the end and returns false. You have not get grasped the way recursion works so your description of what's happening is some way off the mark. Any recursive call that does find obj.hasOwnProperty(prop) to be true *will* "stop" at the return, but that is not going to be the value of the top-level call. For example, take the simpler call hasOwnPropertyDeep({id: "x", main: { temp: 200 }}, "temp") Here, obj.hasOwnProperty(prop) will be false so the code enters the for loop. The first p ("id") gives a type of "string" but the second, "main", has type "object". You call hasOwnPropertyDeep({temp: 200}, "temp") which will return 200 but you throw that value away and go round the loop again. Now the properties are exhausted, the loop ends and the top-level call returns false. The fix is not hard (but I won't write it out unless you want me to since you'll have more fun doing it yourself), but you should think about the design of this function. Do you really need it? What happens if the value of a property is false? What do you want to happen when there are two or more possible results? -- Ben.