0

I got this json object from Kairos face detection api:

"landmarks":[
    {"leftEyeBrowOuterLeft":{"x":38,"y":76}},
    {"leftEyeBrowInnerLeft":{"x":47,"y":74}},
    {"leftEyeBrowInnerRight":{"x":56,"y":76}},
    {"leftEyeBrowOuterRight":{"x":65,"y":80}},
    {"rightEyeBrowOuterLeft":{"x":78,"y":78}},
...
    {"lowerLipTopInnerLeft":{"x":68,"y":139}}]

To draw it i don't know how to access the data in another way than this:

var p=json.frames[0]["people"][0]["landmarks"];
 context.beginPath();  
 context.lineTo(p[0].leftEyeBrowOuterLeft.x,p[0].leftEyeBrowOuterLeft.y);
 context.lineTo(p[3].leftEyeBrowOuterRight.x,p[3].leftEyeBrowOuterRight.y);
 context.stroke();

I guess the best way would be to get rid of the array structure ?! So it would look like this:

...
context.lineTo(p.leftEyeBrowOuterLeft.x,p.leftEyeBrowOuterLeft.y);
...

But how do i rearrange it ?

Flemming
  • 694
  • 7
  • 22
  • I'm not sure, if [this question](http://stackoverflow.com/questions/11922383/access-process-nested-objects-arrays-or-json) is a dup, but it is useful reading anyway. – Teemu Dec 24 '16 at 11:16
  • 1
    What you are asking doesn't make sense. You either need array or not, single element or multiple. Decide first what you need. Nothing wrong with array. – dfsq Dec 24 '16 at 11:16
  • It should be obvious that there can be no single general answer to the question as posed in the title. – Pointy Dec 24 '16 at 11:19
  • I think doing `p.leftEyeBrowOuterLeft.x,p.leftEyeBrowOuterLeft.y` definitely won't work. You probably want to create a `for loop` to go through all the people instead. Show us your full JSON – Samuel Toh Dec 24 '16 at 11:19
  • You rearrange it by writing code to do it. Where are you stuck? – melpomene Dec 24 '16 at 11:22
  • Here's a link to documentation showing the rest of the json object https://www.kairos.com/docs/api/#post-v2media . I'm asking because im not strong in javascript and dont really understand why the Kairos theme made this structure. They are talking about adding additional feature points which could lead to later inconvenience with this array structure. – Flemming Dec 24 '16 at 11:51

1 Answers1

2

Assuming that array as returned by the API contains objects with a single property as in the question, and that no property name is repeated, you can just use .reduce() to collapse the array into an object:

var landmarkProps = json.frames[0].people[0].landmarks.reduce(function(o, l) {
  var properties = Object.keys(l);
  // should be just one, but just in case check for all properties
  properties.forEach(function(prop) {
    // it would be an error here for o[prop] to be already set,
    // so one could check for that if the API might do that
    o[prop] = l[prop];
  });
  return o;
}, {});

That will leave you with a single object containing all the landmark properties from the array, without the need to index into an array. The result of that would be that landmarkProps would look like:

{
  "leftEyeBrowOuterLeft": {"x":38,"y":76},
  "leftEyeBrowInnerLeft": "x":47,"y":74},
  "leftEyeBrowInnerRight": {"x":56,"y":76},
  "leftEyeBrowOuterRight": {"x":65,"y":80},
  "rightEyeBrowOuterLeft": {"x":78,"y":78},
  // ...
}
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Thank's @Pointly, this is a beautiful solution that i couldn't have come up with my self! ...and it works! :-) – Flemming Dec 24 '16 at 12:09