1

How can I split an array of images among an object?

For example, using the JSON below. How can produce a return string of each itemUrl and it's associated productCode?

This JSON

{
  "products": [
    {
      "productCode": "ID1",
      "images": [
        {
          "id": 1,
          "itemUrl": "https://img.com/1.JPG"
        },
        {
          "id": 2,
          "itemUrl": "https://img.com/2.JPG"
        }
      ]
    },
    {
      "productCode": "ID2",
      "images": [
        {
          "id": 3,
          "itemUrl": "https://img.com/3.JPG"
        },
        {
          "id": 4,
          "itemUrl": "https://img.com/4.JPG"
        },
        {
          "id": 5,
          "itemUrl": "https://img.com/5.JPG"
        }
      ]
    }
  ]
}

Becomes

https://img.com/1.JPG
https://img.com/2.JPG
https://img.com/3.JPG
https://img.com/4.JPG
https://img.com/5.JPG

Currently, if I were to use

for (const tour of data.products) {
  console.log(tour.images[0].itemUrl);
  ...

the return would obviously return

https://img.com/1.JPG
https://img.com/3.JPG

however, when

let imageEach = tour.images;
let output = [];
imageEach.forEach(item => {
  output.push(item.itemUrl);
});
  ...

I get a return of

[{
  https://img.com/1.JPG,
  https://img.com/2.JPG
}]

[{
  https://img.com/3.JPG
  https://img.com/4.JPG
  https://img.com/5.JPG
}]

6 Answers 6

6

You can try something like this using Array.reduce to iterate over the products and Array.map to go through the items and get the itemUrl:

const data = { "products": [ { "productCode": "ID1", "images": [ { "id": 1, "itemUrl": "https://img.com/1.JPG" }, { "id": 2, "itemUrl": "https://img.com/2.JPG" } ] }, { "productCode": "ID2", "images": [ { "id": 3, "itemUrl": "https://img.com/3.JPG" }, { "id": 4, "itemUrl": "https://img.com/4.JPG" }, { "id": 5, "itemUrl": "https://img.com/5.JPG" } ] } ] } 

const result = data.products.reduce((r,{images}) => {
  r.push(...images.map(x => x.itemUrl))
  return r
}, [])
 console.log(result.join('\n'))

Or even shorter as suggested by @Prassana by using ES6 array spread some more:

const data = { "products": [ { "productCode": "ID1", "images": [ { "id": 1, "itemUrl": "https://img.com/1.JPG" }, { "id": 2, "itemUrl": "https://img.com/2.JPG" } ] }, { "productCode": "ID2", "images": [ { "id": 3, "itemUrl": "https://img.com/3.JPG" }, { "id": 4, "itemUrl": "https://img.com/4.JPG" }, { "id": 5, "itemUrl": "https://img.com/5.JPG" } ] } ] } 

const result = data.products.reduce((r,{images}) => 
  [...r, ...images.map(x => x.itemUrl)], [])

console.log(result.join('\n'))

Sign up to request clarification or add additional context in comments.

5 Comments

since you have already used rest operators what is the point of push here ? you can simple return [...r, ...images.map(x => x.itemUrl) ]
Very good point. No reason other than hobbit and trying to type quick :). Will update. Thanks.
Thank you very much but this still returns as an array rather than individual strings. Reading back at my question, it perhaps is not the clearest.
I mean you can join and have it as string etc. See updated answer. You can also simply spread the array console.log(...result)
Thank you. It does what I asked for, unlikely to work in my issue but I should have been more detailed in my questioning. Thanks again.
0

Try

var result = [];
for (var i = 0; i < data.products.length; i++) {
    for (var j = 0; j < data.products[i].images.length; j++){
        result.push(data.products[i].images[j].itemUrl);
    }
}
console.log(result);

Comments

0

You need Array.concat

const data = {
  "products": [
    {
      "productCode": "ID1",
      "images": [
        {
          "id": 1,
          "itemUrl": "https://img.com/1.JPG"
        },
        {
          "id": 2,
          "itemUrl": "https://img.com/2.JPG"
        }
      ]
    },
    {
      "productCode": "ID2",
      "images": [
        {
          "id": 3,
          "itemUrl": "https://img.com/3.JPG"
        },
        {
          "id": 4,
          "itemUrl": "https://img.com/4.JPG"
        },
        {
          "id": 5,
          "itemUrl": "https://img.com/5.JPG"
        }
      ]
    }
  ]
}

let urls =  []
data.products.forEach(item => {
  urls = urls.concat(item.images.map(img => img.itemUrl))
})

console.log(urls)

Comments

0

You could try this.

let json = {
  "products": [
    {
      "productCode": "ID1",
      "images": [
        {
          "id": 1,
          "itemUrl": "https://img.com/1.JPG"
        },
        {
          "id": 2,
          "itemUrl": "https://img.com/2.JPG"
        }
      ]
    },
    {
      "productCode": "ID2",
      "images": [
        {
          "id": 3,
          "itemUrl": "https://img.com/3.JPG"
        },
        {
          "id": 4,
          "itemUrl": "https://img.com/4.JPG"
        },
        {
          "id": 5,
          "itemUrl": "https://img.com/5.JPG"
        }
      ]
    }
  ]
}
json.products.forEach(product => {
     console.log(product.productCode + ": ")
     product.images.forEach(i => console.log(i.itemUrl))                       
});

// or 
json.products.forEach(product => {
     product.images.forEach(i => console.log(product.productCode + " : " + i.itemUrl))  
});

Comments

0
products.reduce((urls, product, i) => {
  const imageURLs = product.images.map(img => img.itemUrl);
  urls = urls.concat(imageURLs);
  return urls;
}, []);

Try this

Comments

0

You can try my code to produce following result

{
 "ID1" : ["https://img.com/1.JPG","https://img.com/2.JPG"],
 "ID2" : ["https://img.com/3.JPG","https://img.com/4.JPG","https://img.com/5.JPG"]
}

Below is the code. Lets take your mentioned JSON data as "obj"(a variable)

 obj.products.reduce((acc, product)=>{
   acc[product.productcode] = product.images.map(img => img.itemUrl)
   return acc
 }, {})

Comments

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.