Home > Software engineering >  Joining and filtering two data sets
Joining and filtering two data sets

Time:04-05

I am currently having difficulties filtering and joining 2 data sets based on various conditions.

The data I am receiving is like so

const ob = {
  "dataOne": [
    {
      "type": "Type 1",
      "name": "failed"
    },
    {
      "type": "Type 1",
      "name": "success"
    },
    {
      "type": "Type 2",
      "name": "success"
    },
    {
      "type": "Type 3",
      "name": "success"
    },
  ],
  "dataTwo": [
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 3",
      "name": "click",
    },
  ]
};

The result I am after is like so

{
    "type 1" : [
        {
            "count": 2
            "success": 1
            "failed": 1
            "clicks": 2
        }
    ],
    "type 2" : [
        {
            "count": 1
            "success": 1
            "failed": 0
            "clicks": 2
        }
    ],
    "type 3" : [
        {
            "count": 1
            "success": 1
            "failed": 0
            "clicks": 1
        }
    ]
}

So what I am essentially aiming to do is get the unique types from dataOne. I then need the total count of occurrences for each type. Then, I need to know for each type the total count of success and failed.

Then from dataTwo I need to include the number of clicks for each type.

To start things off (not sure if I am going in the right direction here), I have done

const result = ob.dataOne.reduce( (acc, o) => (acc[o.type] = (acc[o.type] || 0) 1, acc), {} );

This will give me the total counts for each type. However, I am not sure how to check the success and failed and format it like above.

Any advice appreciated. I started a JSFiddle

Thanks

CodePudding user response:

I think is easier to concat the two datasets first and then reduce. Here is my code for this:

const ob = {
  "dataOne": [
    {
      "type": "Type 1",
      "name": "failed"
    },
    {
      "type": "Type 1",
      "name": "success"
    },
    {
      "type": "Type 2",
      "name": "success"
    },
    {
      "type": "Type 3",
      "name": "success"
    },
  ],
  "dataTwo": [
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 3",
      "name": "click",
    },
  ]
};

const concatenatedArrays = ob.dataOne.concat(ob.dataTwo);

const result = concatenatedArrays.reduce((acc, o) => {
  if (!acc[o.type]) {
    acc[o.type] = [{
      "count": 0,
      "success": 0,
      "failed": 0,
      "click": 0,
    }];
  }
  if(o.name == "failed" || o.name == "success"){
    acc[o.type][0]['count'] = (acc[o.type][0]['count'] || 0)   1;

  }

  acc[o.type][0][o.name] =  acc[o.type][0][o.name]  1

  return acc;
}, {}); 

console.log(result);

EDIT:

Hmm so the count is just for dataOne, changing the code and using reduce twice:

const ob = {
  "dataOne": [
    {
      "type": "Type 1",
      "name": "failed"
    },
    {
      "type": "Type 1",
      "name": "success"
    },
    {
      "type": "Type 2",
      "name": "success"
    },
    {
      "type": "Type 3",
      "name": "success"
    },
  ],
  "dataTwo": [
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 2",
      "name": "click",
    },
    {
      "type": "Type 1",
      "name": "click",
    },
    {
      "type": "Type 3",
      "name": "click",
    },
  ]
};

const dataOneReduced = ob.dataOne.reduce((acc, o) => {
  if (!acc[o.type]) {
    acc[o.type] = [
      {
        count: 0,
        success: 0,
        failed: 0,
        click: 0,
      },
    ];
  }

  acc[o.type][0]["count"] = (acc[o.type][0]["count"] || 0)   1;
  acc[o.type][0][o.name] = acc[o.type][0][o.name]   1;

  return acc;
}, {});

const result = ob.dataTwo.reduce((acc, o) => {
  acc[o.type][0][o.name] = acc[o.type][0][o.name]   1;

  return acc;
}, dataOneReduced);

console.log(result);

  • Related