3
\$\begingroup\$

So this original piece of code:

const imgUrls = {};

function onXhrLoad() {
  const json = JSON.parse(this.response);
  const photos = json.photos ? json.photos.photo : [json.photo];
  for (const {id, url_o} of photos) {
    imgUrls[id] = url_o;
  }
}

The original code assumed that the biggest available url to an image in the object "photos" is "url_o", but sometimes that size is not available so I wanted to change the "url_o" in the last 2 lines to the biggest size available in "photos" using the array size (array "size" in the modified code is the order of sizes from biggest to smallest).

so I modified the code as follows:

const imgUrls = {};
const sizes = ['url_o', 'url_6k', 'url_5k', 'url_4k', 'url_3k', 'url_k', 'url_h', 'url_l'];

function onXhrLoad() {
  const json = JSON.parse(this.response);
  const photos = json.photos ? json.photos.photo : [json.photo];
  for (var p of photos) {
    for (var s of sizes) {
        if (s in p) {
            var url = p[s];
            break;
        }
    }
    const id = p.id;
    imgUrls[id] = url;
  }
}

As requested in a comment, there is an example response at this link. In this response there is no url_o, the biggest is url_6k

My question is if there is a better way to change the "url_o" than going through two for loops and an if condition.

\$\endgroup\$
  • \$\begingroup\$ Can you add sample responses to your question to add more context? \$\endgroup\$ – konijn Nov 5 at 21:45
  • \$\begingroup\$ To close voters, there is enough context for me (once we have a JSON sample) \$\endgroup\$ – konijn Nov 5 at 21:56
  • \$\begingroup\$ The response is huge, will add it in an external link then \$\endgroup\$ – Vagabond Nov 5 at 22:06
  • 1
    \$\begingroup\$ @konijn I added the code for the response \$\endgroup\$ – Vagabond Nov 5 at 22:17
  • 3
    \$\begingroup\$ Consider also editing the post title to summarize the purpose of the code (as per the watermark text in the title field) - as it stands every single on-topic question on this site could have that exact same title: this question is implicit in every CR post - rule of thumb, if your title is worded like a question, it's probably a poor title for your CR post (yes, we realize this isn't necessarily obvious given we're technically a Q&A site ;-) \$\endgroup\$ – Mathieu Guindon Nov 6 at 0:39
4
\$\begingroup\$
  • find the first "biggest" url size name. A more convenient way is using Array.prototype.find() method:

  • p.id can be used directly as a key for object imgUrls - instead of generating constant const id = p.id; for each p(photo)


const imgUrls = {};
const sizes = ['url_o', 'url_6k', 'url_5k', 'url_4k', 'url_3k', 'url_k', 'url_h', 'url_l'];


function onXhrLoad() {
  const json = JSON.parse(js);
  const photos = json.photos ? json.photos.photo : [json.photo];
  for (var p of photos) {   
      imgUrls[p.id] = p[sizes.find((s) => p[s])];
  }
}
\$\endgroup\$
  • \$\begingroup\$ Thank you, that seems to do the trick. just to make sure I understand what you did correctly, does this mean that "sizes.find" will take the first entry of "sizes" name it "s" and check if it exists in "p", if it does, it will use that value of "s", if not it will move on to the next entry in "s" in order check again and keep on going and until it finds a match? \$\endgroup\$ – Vagabond Nov 6 at 9:32
  • 1
    \$\begingroup\$ @Vagabond, Yes, you got it right \$\endgroup\$ – RomanPerekhrest Nov 6 at 9:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.