使用javascript对元素列表进行分类/分组和排序的最佳方法是什么?

时间:2016-08-27 05:52:38

标签: javascript jquery

我有一些元素列表,其中包含一些属性,如

<?php
//if registered_date is older then 2 months from current date
date_default_timezone_set('Europe/London');
$registered_date = new DateTime('2016-06-05');

$now = new DateTime();
$interval = new DateInterval('P2M');
$checkDate = $now->sub($interval);

if($registered_date > $checkDate ) {
  echo "insert";
} else {
  echo "not insert";
}

其他可能的类别可以是纸张,文章等。

现在,假设有两个按钮“按类别排序”和“按年份排序”。

点击“按类别排序”时,列表应为:

doc.title = 'some title'
doc.category = 'book'
doc.year = '2016'

点击“按年排序”按钮时

Book
1. book 1
2. book 2

Paper
1. paper 1
2. paper 2

Article
1. article 1
2. article 2

等等。

我希望在保持html页面大小尽可能小的同时做到这一点。请让我知道实现这一目标的最佳方法是什么。

1 个答案:

答案 0 :(得分:1)

这样的事情应该让你开始 - 代码注释了解释(see it in action):

// convert array of objects into a Map grouped and ordered by supplied key
function group(items, key) {
    // get unique values for grouping key
    const unique = [
        ...new Set(items.map(item => item[key]))
    ];

    // will be ascending by default
    unique.sort();

    // sorting all of the results by title field
    const sortFn = (a, b) => a.title > b.title;

    const sortItems = (val) => {
        // filters the result set to items sharing the current group field value
        let sorted = items.filter(item => item[key] === val);
        // sort by title
        sorted.sort(sortFn);
        return sorted;
    }

    // reduce to a Map (which preserves insertion order and maintains the group key sorting)
    return unique.reduce((map, cur) => map.set(cur, sortItems(cur)), new Map());
}

// testing it out
data = [{
  title: 'foo',
    category: 'book',
    year: 2016,
}, {
    title: 'bar',
    category: 'book',
    year: 2016,
}, {
    title: 'blah',
    category: 'paper',
    year: 2010,
}, {
    title: 'idk',
    category: 'paper',
    year: 2015,
}]

group(data, 'category'); // Map {"book" => [Object, Object], "paper" => [Object, Object]}
group(data, 'year'); // Map {2010 => [Object], 2015 => [Object], 2016 => [Object, Object]}

要进行显示,您可以使用for...of进行解构:

for (let [category, items] of group(data, 'category')) {
    console.log(`
       <div class="item">
          <h3>${category}</h3>
          <ol>${items.map(item => `<li>${item.title}</li>`).join('')}</ol>
       </div>
    `);
}

请注意,即使我在整个过程中使用了ES6,也可以轻松地将其重构为更向后兼容的