4

I have an array of objects that I would like to turn into an array (or array-like) object where the keys are the unique values for that given property (something like SQL group by).

fiddle:

var obj = [
   {
      "ClaimId":"111",
      "DrugName":"AMBIEN CR",
      "PatientId":1571457415
   },
   {
      "ClaimId":"222",
      "DrugName":"AMBIEN CR",
      "PatientId":1571457415
   },
   {
      "ClaimId":"333",
      "DrugName":"LOTREL",
      "PatientId":1571457415
   },
   {
      "ClaimId":"444",
      "DrugName":"METHYLPREDNISOLONE",
      "PatientId":1571457415
   },
   {
      "ClaimId":"555",
      "DrugName":"CYMBALTA",
      "PatientId":1513895252
   },
   {
      "ClaimId":"666",
      "DrugName":"CYMBALTA",
      "PatientId":1513895252
   },
   {
      "ClaimId":"777",
      "DrugName":"CYMBALTA",
      "PatientId":1513895252
   },
   {
      "ClaimId":"888",
      "DrugName":"CYMBALTA",
      "PatientId":1513895252
   },
   {
      "ClaimId":"147503879TMQ",
      "DrugName":"CYMBALTA",
      "PatientId":1513895252
   },
   {
      "ClaimId":"999",
      "DrugName":"CYMBALTA",
      "PatientId":1513895252
   }
]
function splitBy(data, prop) {
        var returnObj = {};
        var returnArray = [];
        $.each(data, function (ix, val) {
            if (returnObj[val[prop]] === undefined) {
                returnObj[val[prop]] = [];
                returnObj[val[prop]].push(val);
            }


        });
        console.log(returnObj);
    }
splitBy(obj,'PatientId');

In the fiddle you can see that I get the keys of the array like I want (the two unique values in the PatientId property) but I only get the first value. I understand that's because once the key is no longer undefined, then this check isn't ran, but I couldn't figure out quite how to do it and this is as close as I got. How can I do this with one iteration over this collection?

2 Answers 2

4

I only get the first value.

That's because you only push the first value - when there had been no key. Change the

        if (returnObj[val[prop]] === undefined) {
            returnObj[val[prop]] = [];
            returnObj[val[prop]].push(val);
        }

to

        if (returnObj[val[prop]] === undefined) {
            returnObj[val[prop]] = [];
        }
        returnObj[val[prop]].push(val);
Sign up to request clarification or add additional context in comments.

1 Comment

After a few minutes of looking, this is exactly that I was trying to do with ternary logic if the val[prop] === something something..here, you simply push it onto the correct key because the correct key is what's being iterated over. Thanks :)
1

jsFiddle Demo

You almost had it, but you forgot the else clause for once the key existed

if (returnObj[val[prop]] === undefined) {
    returnObj[val[prop]] = [];
    returnObj[val[prop]].push(val);
}else{
    returnObj[val[prop]].push(val);
}

7 Comments

No, using else and an empty array literal would ignore the first occurence.
With the else you have the same line twice; it shouldn't be in the if at all, because you want it to run every time.
@Bergi I thought you were wrong at first, but...I was wrong when I realized that my new array was only 8 elements :(
@Bergi - In your version it would. But not in the OP's code. Your comment is not relevant.
@Mathletics - That is true, the else is not essentially required as much as the inclusion of the push, it is more of a readability issue. However, without refactoring the op's code, it is required.
|

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.