Scott
Scott

Reputation: 1310

Group items in an array by date

i have an array which contains dates and bin colors. Some bins are collected on the same date so i want to group these dates then have an array of bin colors.

The data structure i'm looking to achieve is:

"items": [
        "item": {
            "date": "2019-10-18T00:00:00.000Z",
            "bins": [{
                "bin": "Blue"
            }, {
                "bin": "Grey"
            }]
        },
        ...
]

Data array:

var dateList = [{
        "date": "2019-10-18T00:00:00.000Z",
        "bin": "Blue"
    }, {
        "date": "2019-11-08T00:00:00.000Z",
        "bin": "Blue"
    }, {
        "date": "2019-11-01T00:00:00.000Z",
        "bin": "Green"
    }, {
        "date": "2019-11-22T00:00:00.000Z",
        "bin": "Green"
    }, {
        "date": "2019-10-18T00:00:00.000Z",
        "bin": "Grey"
    }, {
        "date": "2019-11-01T00:00:00.000Z",
        "bin": "Grey"
    }]

Here's the code i have so far, it's almost there but instead of creating items.item it creates items[date], but i can't figure out the last part:

    var items = {};
    for(var i = 0; i < dateList.length; i++) {

        if(!items[dateList[i].date]) {

            items[dateList[i].date] = {};
            items[dateList[i].date].date = dateList[i].date;
            items[dateList[i].date].bins = [];
            items[dateList[i].date].bins.push( { "bin": dateList[i].bin });

        } else {
            items[dateList[i].date].bins.push( { "bin": dateList[i].bin }); 
        }
    } 

This results in items[date]

"items": {
    "2019-10-18T00:00:00.000Z": {
        "date": "2019-10-18T00:00:00.000Z",
        "bins": [{
            "bin": "Blue"
        }, {
            "bin": "Grey"
        }]
    },
    "2019-11-08T00:00:00.000Z": {
        "date": "2019-11-08T00:00:00.000Z",
        "bins": [{
            "bin": "Blue"
        }]
    },
    "2019-11-01T00:00:00.000Z": {
        "date": "2019-11-01T00:00:00.000Z",
        "bins": [{
            "bin": "Green"
        }, {
            "bin": "Grey"
        }]
    },
    "2019-11-22T00:00:00.000Z": {
        "date": "2019-11-22T00:00:00.000Z",
        "bins": [{
            "bin": "Green"
        }]
    }
}

I would prefer it if i could structure it like items.item

"items": [
    "item": {
        "date": "2019-10-18T00:00:00.000Z",
        "bins": [{
            "bin": "Blue"
        }, {
            "bin": "Grey"
        }]
    },
    "item": {
        "date": "2019-11-08T00:00:00.000Z",
        "bins": [{
            "bin": "Blue"
        }]
    },
    "item": {
        "date": "2019-11-01T00:00:00.000Z",
        "bins": [{
            "bin": "Green"
        }, {
            "bin": "Grey"
        }]
    },
    "item": {
        "date": "2019-11-22T00:00:00.000Z",
        "bins": [{
            "bin": "Green"
        }]
    }
]

thanks

Upvotes: 0

Views: 174

Answers (3)

vinoth
vinoth

Reputation: 306

First, the result you are expecting is invalid. The javascript array will not accept the key values. The array is the list of items or objects. Below is the output you can get.

//Output
[
  {
    "date": "2019-10-18T00:00:00.000Z",
    "bins": [
      {
        "bin": "Blue"
      },
      {
        "bin": "Grey"
      }
    ]
  },
  {
    "date": "2019-11-08T00:00:00.000Z",
    "bins": [
      {
        "bin": "Blue"
      }
    ]
  },
  {
    "date": "2019-11-01T00:00:00.000Z",
    "bins": [
      {
        "bin": "Green"
      },
      {
        "bin": "Grey"
      }
    ]
  },
  {
    "date": "2019-11-22T00:00:00.000Z",
    "bins": [
      {
        "bin": "Green"
      }
    ]
  }
]

Below is the javascript code to derive the output.

//Code
var noDuplicates = [];
var lookupObject  = {};
for(var i in dateList) {
    lookupObject[dateList[i]['date']] = dateList[i];
}

//Create the array with unique dates
for(i in lookupObject) {
    noDuplicates.push(lookupObject[i].date);
}

var results=[]
//Iterate and filter the original array with same date value
for(i in noDuplicates) {
    var groupedArray = dateList.filter(obj => {
      return obj.date === noDuplicates[i]
    })
    //Form the bins array for the output
    var bins = groupedArray.map(obj => {
      return {
        'bin': obj.bin
      }
    })
    //Construct the output object
    results.push({
      'date': groupedArray[0].date,
      'bins': bins
    })
}

Yes. It is a straight forward solution with little bit of manipulation for getting the unique values first. Hope it resolves your problem.

Upvotes: 0

Alberto Chiesa
Alberto Chiesa

Reputation: 7350

My take on this:

var dateList = [{
    "date": "2019-10-18T00:00:00.000Z",
    "bin": "Blue"
}, {
    "date": "2019-11-08T00:00:00.000Z",
    "bin": "Blue"
}, {
    "date": "2019-11-01T00:00:00.000Z",
    "bin": "Green"
}, {
    "date": "2019-11-22T00:00:00.000Z",
    "bin": "Green"
}, {
    "date": "2019-10-18T00:00:00.000Z",
    "bin": "Grey"
}, {
    "date": "2019-11-01T00:00:00.000Z",
    "bin": "Grey"
}]

let dictionary = {};
for(let i = 0; i < dateList.length; i++) {
  const item = dateList[i];
  if (!dictionary[item.date]) dictionary[item.date] = { date: item.date, bins: [] };
  dictionary[item.date].bins.push(item.bin);
}

const result = Object.values(dictionary);

// if you need to have distinct values in bins:
result.forEach(obj => obj.bins = new Array(...new Set(obj.bins)));

console.log(result);

Upvotes: 1

libik
libik

Reputation: 23029

To get array of objects, you can use it as the following code. Please note that the order when using Object.keys() is not guaranteed.

I put there two methods, one is just simple array, the second one is array with item keyword as the wrapper for each object in array.

const items = {
    "2019-10-18T00:00:00.000Z": {
        "date": "2019-10-18T00:00:00.000Z",
        "bins": [{
            "bin": "Blue"
        }, {
            "bin": "Grey"
        }]
    },
    "2019-11-08T00:00:00.000Z": {
        "date": "2019-11-08T00:00:00.000Z",
        "bins": [{
            "bin": "Blue"
        }]
    },
    "2019-11-01T00:00:00.000Z": {
        "date": "2019-11-01T00:00:00.000Z",
        "bins": [{
            "bin": "Green"
        }, {
            "bin": "Grey"
        }]
    },
    "2019-11-22T00:00:00.000Z": {
        "date": "2019-11-22T00:00:00.000Z",
        "bins": [{
            "bin": "Green"
        }]
    }
}

const array = Object.keys(items).map(key => items[key]);
const arrayWithItems = Object.keys(items).map(key => ({item: items[key]}));
console.log(array);
console.log('!!!! -------- !!!!!');
console.log(arrayWithItems);

Upvotes: 1

Related Questions