按日期分组对象数组

时间:2017-05-01 06:25:07

标签: javascript momentjs lodash

我有一个看起来像这样的数据结构

const arr = [{
    name: "Alice",
    created_at : "2017-04-18"
},
{
    name: "James",
    created_at : "2017-06-30"
},
{
    name: "Melisa",
    created_at : "2017-04-03"
},
{
    name: "Amy",
    created_at : "2017-05-03"
}];

我想重组它以便我可以显示它们。我希望按月显示它们,就像这样

四月 - 爱丽丝 - Melisa

五月 - 艾米

六月 - 詹姆斯

我不知道从哪里开始。

6 个答案:

答案 0 :(得分:9)

这是一个使用时刻和lodash的解决方案。

首先,我们创建一个帮助函数,使用moment创建日期,然后提取缩短的月份名称。

// helper function to get the month name from an item
const monthName = item => moment(item.created_at, 'YYYY-MM-DD').format('MMM');

现在使用lodash到group by日期,然后在每个组中使用map来获取每个组的名称。以下代码段使用隐式chaining

// group items by month name and then get the name for each month
const result = _(arr)
    .groupBy(monthName)
    .mapValues(items => _.map(items, 'name'))
    .value()

如上所述,但有明确的链接:

// group items by month name and then get the name for each month
const result = _.chain(arr)
    .groupBy(monthName)
    .mapValues(items => _.map(items, 'name'))
    .value()

<强>更新

为了获得每个月的所有项目,它简化为:

const result = _.groupBy(arr, monthName);

result现在看起来像这样:

{
    Apr: [
        { name: "Alice", created_at : "2017-04-18" },
        { name: "Melisa", created_at : "2017-04-03" }
    ],
    Jun: .....
}

答案 1 :(得分:0)

我认为您希望根据月份对它们进行分组,然后使用Array#reduce方法和引用对象来保存索引。

App.xaml.cs

答案 2 :(得分:0)

试试这个

&#13;
&#13;
var res = [
    {month:"January",elems:[]},
    {month:"February",elems:[]},
    {month:"March",elems:[]},
    {month:"April",elems:[]},
    {month:"May",elems:[]},
    {month:"June",elems:[]},
    {month:"July",elems:[]},
    {month:"August",elems:[]},
    {month:"September",elems:[]},
    {month:"October",elems:[]},
    {month:"November",elems:[]},
    {month:"December",elems:[]}
];

const arr = [{
        name: "Alice",
        created_at: "2017-04-18"
    },
    {
        name: "James",
        created_at: "2017-06-30"
    },
    {
        name: "Melisa",
        created_at: "2017-04-03"
    },
    {
        name: "Amy",
        created_at: "2017-05-03"
    }];
arr.forEach(function(e){
    var month =parseInt(e.created_at.substring(5,7)) - 1;
    res[month].elems.push(e);
});
res.forEach(function (e) {
    if (e.elems.length > 0) {
        console.warn(e.month);
        e.elems.forEach(function (n) {
            console.info(n.name);
        });
        console.log('------------------------');
    }
});
console.log(res);
&#13;
&#13;
&#13;

我希望这有效:)

答案 3 :(得分:0)

您可以使用普通的javascript使用key-value对这样的组对它们进行分组。您也可以自动sorted订单

const arr = [{ name: "Alice", created_at : "2017-04-18" }, { name: "James", created_at : "2017-06-30" }, { name: "Melisa", created_at : "2017-04-03" }, { name: "Amy", created_at : "2017-05-03" }];

var m =['','January','February','March','April','May','June','July','August','September','October','November','December'];

var result={}

// restructuring loop
for(var i=0;i<arr.length;i++){
  var month = parseInt(arr[i].created_at.substring(5,7))
  if(!result[month]){
    result[month] = [arr[i].name]
  }
  else{
    result[month].push(arr[i].name)
  }
}

//display loop
for (var k in result){
    if (result.hasOwnProperty(k)) {
         console.log(m[k]+'-->'+result[k])
    }
}

答案 4 :(得分:0)

我们可以使用moment#format获取月份名称,并将其与lodash#groupBy一起使用,以按月对项目进行分组。最后,使用lodash#mapValueslodash#map按名称转换每个项目。

var result = _(arr)
  .groupBy(v => moment(v.created_at).format('MMMM'))
  .mapValues(v => _.map(v, 'name'))
  .value();

const arr = [{
    name: "Alice",
    created_at : "2017-04-18"
},
{
    name: "James",
    created_at : "2017-06-30"
},
{
    name: "Melisa",
    created_at : "2017-04-03"
},
{
    name: "Amy",
    created_at : "2017-05-03"
}];

var result = _(arr)
  .groupBy(v => moment(v.created_at).format('MMMM'))
  .mapValues(v => _.map(v, 'name'))
  .value();
  
console.log(result);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>

答案 5 :(得分:0)

您可以在一个数组中收集月份数据,其中月份值表示数组的索引,并最后过滤数组仅用于真值。

var array = [{ name: "Alice", created_at: "2017-04-18" }, { name: "James", created_at: "2017-06-30" }, { name: "Melisa", created_at: "2017-04-03" }, { name: "Amy", created_at: "2017-05-03" }],
    month = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
    result = array.reduce(function (r, a) {
        var m = a.created_at.slice(5, 7) - 1; // get month number zero based
        if (!r[m]) {                          // check month if exist in result set
            r[m] = [month[m], []];            // if not create a new result set
        }
        r[m][1].push(a.name);                 // push the actual name 
        return r;                             // return temporary result
    }, []).filter(Boolean);                   // filter only months with values

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }