如何在功能上将各个时间戳汇总到时间范围内

时间:2017-03-21 11:44:50

标签: javascript dictionary filter functional-programming reduce

为标题道歉,如果你能想到更好的标题,请编辑!

我最近开始尝试在JavaScript中使用更多map / filter / reduce操作,我有一个问题,我想解决这个问题,我想知道最好的功能方法!

我有一个来自DB的行列表,其中包含'time'列。

{[x, y, 15:10, z], [x, y, 15:20, z], [x, y, 16:10, z]}

我想采用这个数据集,然后吐出一个看起来像的不同数据集:

[{timebox: "15:00-16:00", count: 2}, {timebox: "16:00-17:00", count: 1}]

我可以想办法做一些包含几个操作的方法(例如每个'time-box'只写几个过滤语句)但是我要问的是有一个干净,简单的方法来实现这个目的吗?

4 个答案:

答案 0 :(得分:1)

您可以分割时间并仅将哈希对象的小时部分。



function getTimebox(t) {
    return [t, (+t + 1) % 24].map(v => ('00' + v).slice(-2) + ':00').join('-');
}

var array = [['x', 'y', '15:10', 'z'], ['x', 'y', '15:20', 'z'], ['x', 'y', '16:10', 'z'], ['x', 'y', '23:23', 'z']],
    result = array.reduce(function (hash) {
        return function (r, a) {
            var timebox = a[2].split(':')[0];
            if (!hash[timebox]) {
                hash[timebox] = { timebox: getTimebox(timebox), count: 0 };
                r.push(hash[timebox]);
            }
            hash[timebox].count++;
            return r;
        };
    }(Object.create(null)), []);

console.log(result);

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




使用Map

更紧凑的风格



var getT = t => [t, (+t + 1) % 24].map(v => ('00' + v).slice(-2) + ':00').join('-'),
    array = [['x', 'y', '15:10', 'z'], ['x', 'y', '15:20', 'z'], ['x', 'y', '16:10', 'z'], ['x', 'y', '23:23', 'z']],
    result = array.reduce(
        (map => (r, a) => 
            (t =>
                (!map.has(t) && map.set(t, r[r.push({ timebox: getT(t), count: 0 }) - 1]), map.get(t).count++, r)
            )(a[2].split(':')[0])
        )(new Map), []);

console.log(result);

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




答案 1 :(得分:1)

您可以这样做:



var rows = [
  ['x', 'y', '15:10', 'z'], 
  ['x', 'y', '15:20', 'z'], 
  ['x', 'y', '16:10', 'z']
];

var sets = rows.reduce(function(set, row) {
  var currTime = +row[2].split(':')[0] + (+row[2].split(':')[1])/24;
  var key = Math.floor(currTime) + '-' + Math.ceil(currTime);
  set[key] = set[key] || [];
  set[key].push(row);
  return set;
}, {});

var result = Object.keys(sets).map(function(key) {
  return {
    'timebox' : key,
    'count' : sets[key].length
  }
});

console.log(result);




基本上,这会将sets中存储的不同时间间隔的行分类,然后从中创建所需的结果数组。

答案 2 :(得分:1)

使用reduce和filter的实现。不使用散列或地图类型对象,因此聚合数组上的查找是在线性时间内完成的。



Object




答案 3 :(得分:0)

您可以使用类似于下划线public static Dictionary<string, System.Drawing.Image> ExtractImages(string filename, string sourceFileName, string newFileName) { var images = new Dictionary<string, System.Drawing.Image>(); Stream newpdfStream = new FileStream(newFileName, FileMode.Create, FileAccess.ReadWrite); using (var reader = new PdfReader(filename)) { // PdfReader pdfReader = new PdfReader(reader); PdfStamper pdfStamper = new PdfStamper(pdfReader, newpdfStream); PdfContentByte pdfContentByte = pdfStamper.GetOverContent(1); var parser = new PdfReaderContentParser(reader); ImageRenderListener listener = null; for (var i = 1; i <= reader.NumberOfPages; i++) { parser.ProcessContent(i, (listener = new ImageRenderListener())); var index = 1; if (listener.Images.Count > 0) { foreach (var pair in listener.Images) { images.Add(string.Format("{0}_Page_{1}_Image_{2}{3}", System.IO.Path.GetFileNameWithoutExtension(filename), i.ToString("D4"), index.ToString("D4"), pair.Value), pair.Key); index++; { BaseFont baseFont = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, BaseFont.NOT_EMBEDDED); pdfContentByte.SetColorFill(BaseColor.BLUE); pdfContentByte.SetFontAndSize(baseFont, 8); pdfContentByte.BeginText(); pdfContentByte.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "Kevin Cheng - A Hong Kong actor", 400 + index * 10, 600, 0); pdfContentByte.EndText(); } } } } pdfStamper.Close(); return images; } } docs

的内容
countBy

此处,_.countBy( (row) => { return getInterval(row[2]); } ); 应返回指定时间值的时间间隔(您可以使用getInterval实现它)。 它会产生这样一个对象:

Math.floor

从这里开始,转换为数组应该很简单。