-3

Was wondering how to combine similar json keys together to eliminate redundant data. In other words, how do you concatenate values that are similar under the same key rather than having duplicated data? I currently have json data looking like this:

[
    {
        "listing_id": 1,
        "furniture_id": 2,
        "price": 129.99,
        "duration": null,
        "photo_id": 1,
        "url": "http://d3otkl9byfilk1.cloudfront.net/images/COHG3---A_Graceland-Silver-With-Malva-Blue-Grey-Contrast"
    },
    {
        "listing_id": 1,
        "furniture_id": 2,
        "price": 129.99,
        "duration": null,
        "photo_id": 2,
        "url": "https://www.responsive-checkout.com/demo/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/c/o/couch.jpg"
    }
]

How can I combine the redundant keys to make it look like this:

[
    {
        "listing_id": 1,
        "furniture_id": 2,
        "price": 129.99,
        "duration": null,
        "photo_id": 1,
        "url": [{"http://d3otkl9byfilk1.cloudfront.net/images/COHG3---A_Graceland-Silver-With-Malva-Blue-Grey-Contrast", "https://www.responsive-checkout.com/demo/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/c/o/couch.jpg"}]
    }
]
2
  • and what about photo_id key? What do you want to do with it? Commented May 3, 2016 at 23:03
  • If you want to do this properly (sometimes you may need to merge deeper), you should use lodash! Checkout one of my last questions: stackoverflow.com/questions/36928983/… Commented May 3, 2016 at 23:09

2 Answers 2

0

Use reduce

Being initial the first array you provided:

[initial.reduce(function (obj) { return obj })];

This basically implodes the array into its first element and then puts it in an array, it won't be smart enough if you have objects with different values. If that's what you need please be more specific

If you're looking to deduce if you should merge two objects into the first one only if the values are the same for certain properties, this is what you're looking for:

var result = [];

initial.reduce(function (previous, current, index) { 
    if (index === 0) {
        result.push(current);
        return current;
    }
    if (current.prop1 !== previous.prop1
            || current.prop2 !== previous.prop2
            || current.prop3 ...) {
        result.push(current);
    }

    return current;
});

Then again, that won't work if the simmilar objects are not next to one another. You really need to be more specific

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

Comments

0

Okay this was sort of fun. It took me a while, but here is one possible solution. I'm sure there's a better way of doing this, but this works.

Uses Array.prototype.filter and Array.prototype.findIndex(ES6):

const listings = [{ // sample listings with multiple listing_id and duplicates
  "listing_id": 1,
  "furniture_id": 2,
  "price": 129.99,
  "duration": null,
  "photo_id": 1,
  "url": "http://d3otkl9byfilk1.cloudfront.net/images/COHG3---A_Graceland-Silver-With-Malva-Blue-Grey-Contrast"
}, {
  "listing_id": 1,
  "furniture_id": 2,
  "price": 129.99,
  "duration": null,
  "photo_id": 2,
  "url": "https://www.responsive-checkout.com/demo/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/c/o/couch.jpg"
}, {
  "listing_id": 1,
  "furniture_id": 2,
  "price": 129.99,
  "duration": null,
  "photo_id": 2,
  "url": "https://example.com"
}, {
  "listing_id": 2,
  "furniture_id": 2,
  "price": 129.99,
  "duration": null,
  "photo_id": 2,
  "url": "https://www.responsive-checkout.com/demo/media/catalog/product/cache/1/image/9df78eab33525d08d6e5fb8d27136e95/c/o/couch.jpg"
}, {
  "listing_id": 2,
  "furniture_id": 2,
  "price": 129.99,
  "duration": null,
  "photo_id": 2,
  "url": "https://example2.com"
}, {
  "listing_id": 3,
  "furniture_id": 2,
  "price": 129.99,
  "duration": null,
  "photo_id": 2,
  "url": "https://example3.com"
}];

const duplicates = [];

const filteredListings = listings.filter((listing, index, self) => { // filter out all duplicates
  const found = self.findIndex(i => i.listing_id === listing.listing_id);
  if (found !== index) {
    duplicates.push(listing); // add duplicates to duplicate array to be added back in later.
    return false;
  } else return true;
});

duplicates.forEach((duplicate) => { // loop through duplicates to add url back into main array 
  const listIndex = filteredListings.findIndex(listing => listing.listing_id === duplicate.listing_id);
  
  if (Array.isArray(filteredListings[listIndex].url)) {
    filteredListings[listIndex].url.push(duplicate.url);
  } else filteredListings[listIndex].url = [filteredListings[listIndex].url, duplicate.url];
});

document.body.innerHTML = '<pre>' + JSON.stringify(filteredListings, 0, 4) + '</pre>';

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.