1

My target is if the id from digital_assets and products matches then get the value of URL fro digital_assets and ProductName from products object. I'm able to traverse through the object and get the values of digital_assets and products but need some help to compare these two objects based on IDs to get the value of URL and ProductName. Below is what I've done so far.

var data = [{
        "digital_assets": [{
            "id": "AA001",
            "url": "https://via.placeholder.com/150"
        },{
            "id": "AA002",
            "url": "https://via.placeholder.com/150"
        }]
    }, {
        "products": [{
            "id": ["BB001", "AA001"],
            "ProductName": "PROD 485"
        },{
            "id": ["BB002", "AA002"],
            "ProductName": "PROD 555"
        }]
    }
];

$.each(data, function () {
    var data = this;
    //console.log(data);

    $.each(data.digital_assets, function () {
        var dAssets = this,
            id = dAssets['id'];
        // console.log(id);
    });

    $.each(data.products, function () {
        var proData = this,
            prod_id = proData['id'];
        // console.log(prod_id);

        $.each(prod_id, function () {
            var arr_id = this;
            console.log(arr_id);
        });
    });
});

Do I need to create new arrays and push the values into the new arrays? Then concat() these array to one. ? Bit lost any help will be appreciated.

5
  • 2
    Can you add a sample result to your question? I'm not clear on what you want the result to be. Commented Dec 11, 2018 at 20:07
  • Using an if() statement you can simply push() any matching items into a new array. Have you tried this? Commented Dec 11, 2018 at 20:09
  • 1
    There's no such thing as a JSON Array. You have an Array. The fact that it was parsed from JSON is irrelevant, and will only make your searches for answers more difficult. Commented Dec 11, 2018 at 20:17
  • @HereticMonkey i mean... with how often this is done, it may actually make the search for answers easier. Commented Dec 11, 2018 at 20:18
  • @KevinB It would help find recent duplicates, but not duplicates before JSON rolled around ;). Commented Dec 11, 2018 at 20:19

4 Answers 4

1

Here is one way you can do this via Array.reduce, Array.includes, Object.entries and Array.forEach:

var data = [{ "digital_assets": [{ "id": "AA001", "url": "https://via.placeholder.com/150" }, { "id": "AA002", "url": "https://via.placeholder.com/150" } ] }, { "products": [{ "id": ["BB001", "AA001"], "ProductName": "PROD 485" }, { "id": ["BB002", "AA002"], "ProductName": "PROD 555" } ] } ]

const result = data.reduce((r,c) => { 
  Object.entries(c).forEach(([k,v]) => 
    k == 'digital_assets' 
     ? v.forEach(({id, url}) => r[id] = ({ id, url }))
     : v.forEach(x => Object.keys(r).forEach(k => x.id.includes(k) 
       ? r[k].ProductName = x.ProductName 
       : null))
  )
  return r
}, {})

console.log(Object.values(result))

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

Comments

1

You can use Array.prototype.find, Array.prototype.includes and Array.prototype.map to achieve this very gracefully.

let data = [
   {
    "digital_assets": [
      {
        "id": "AA001",
        "url": "https://via.placeholder.com/150"
      },
      {
        "id": "AA002",
        "url": "https://via.placeholder.com/150"
      }
    ]
  },
  {
    "products": [
      {
        "id": ["BB001", "AA001"],
        "ProductName": "PROD 485"
      },
      {
        "id": ["BB002","AA002"],
        "ProductName": "PROD 555"
      }
    ]
  }
];

// Find the 'digital_assets' array
let assets = data.find(d => d['digital_assets'])['digital_assets'];

// Find the 'products' array
let products = data.find(d => d['products'])['products'];

// Return an array of composed asset objects
let details = assets.map(a => {
  return {
    id : a.id,
    url : a.url
    name : products.find(p => p.id.includes(a.id)).ProductName
  };
});

console.log(details);

Comments

0

changed answer to fit your needs:

var data = [
       {
        "digital_assets": [
          {
            "id": "AA001",
            "url": "https://via.placeholder.com/150"
          },
          {
            "id": "AA002",
            "url": "https://via.placeholder.com/150"
          }
        ]
      },
      {
        "products": [
          {
            "id": ["BB001", "AA001"],
            "ProductName": "PROD 485"
          },
          {
            "id": ["BB002","AA002"],
            "ProductName": "PROD 555"
          }
        ]
      }
    ]
let matchingIds = [];
let data_assetsObject = data.find(element => {
    return Object.keys(element).includes("digital_assets")
})
let productsObject = data.find(element => {
    return Object.keys(element).includes("products")
})
data_assetsObject["digital_assets"].forEach(da => {
  productsObject["products"].forEach(product => {
    if (product.id.includes(da.id)){
      matchingIds.push({
        url: da.url,
        productName: product.ProductName
      })
    }
  })
})
console.log(matchingIds);

working fiddle: https://jsfiddle.net/z2ak1fvs/3/

Hope that helped. If you dont want to use a new array, you could also store the respective data within the element you are looping through.

Edit: I think i know why i got downvoted. My example works by making data an object, not an array. changed the snippet to show this more clearly. Why is data an array anyway? Is there any reason for this or can you just transform it to an object?

Edit nr2: changed the code to meet the expectations, as i understood them according to your comments. it now uses your data structure and no matter whats in data, you can now search for the objects containing the digital_assets / products property.

cheers

5 Comments

Thank for the code. I tried your code with the original data structure and used the data[0] for digital_assets and data[1] for products. I understand its the array index is hard coded. Is there a way array can be added dynamically using your code as I can't change the data structure.
@Chip is the data structure always the same?
No, data won't be same. For example, if the new attribute called "Product Category" is added to the data it'll generate the new array of objects just like the one we have for the products. And of course it'll affect the array index value.
@Chip have a look at it one more time. does this fit your needs?
I'll try your edited code. Actually working on API and don't have control over the data structure. Thanks
-1

https://jsfiddle.net/2b1zutvx/

using map.

 var myobj = data[0].digital_assets.map(function(x) {
    return {
        id: x.id,
        url: x.url,
        ProductName: data[1].products.filter(f => f.id.indexOf(x.id) > -1).map(m => m.ProductName)
    };
});

3 Comments

Your code assumes that the Digital_Assets record will always be the first element of the data array and that Products will always be the second. This will break if any other data records are inserted before either of these.
@Bryan Dellinger - Thank for the code. I tried your code with map(). Is it possible data[] can be added dynamically instead of hardcoding the index value?
Data.indexof whatever you want

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.