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 ?

6
  • I'm not sure, if this question is a dup, but it is useful reading anyway. Commented Dec 24, 2016 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. Commented Dec 24, 2016 at 11:16
  • It should be obvious that there can be no single general answer to the question as posed in the title. Commented Dec 24, 2016 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 Commented Dec 24, 2016 at 11:19
  • You rearrange it by writing code to do it. Where are you stuck? Commented Dec 24, 2016 at 11:22

1 Answer 1

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},
  // ...
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank's @Pointly, this is a beautiful solution that i couldn't have come up with my self! ...and it works! :-)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.