2013-05-22 25 views
14

Mam tablicę z następujących wartości (przykład):Javascript Get sekwencyjne daty Array

[ 
     1367848800000: true, 
     1367935200000: true, 
     1368021600000: true, 
     1368108000000: true, 
     1368194400000: true, 
     1368367200000: true, 
     1368540000000: true, 
     1368626400000: true, 
     1368712800000: true 
    ] 

gdzie indeks jest czas, data. Data będzie zawsze o godzinie 00:00 w dniu.

W tym przykładzie pierwszych pięć dat jest następujących po sobie, a następnie jeden dzień, a następnie kolejna grupa 3 dat. Przykład tego, co mam na myśli, znajduje się poniżej.

Dates on Calendar

Teraz, co próbuję zrobić, to znaleźć termin sekwencyjnych i umieścić je na tablicy w następujący sposób:

[ 
     1367848800000, 
     1367935200000, 
     1368021600000, 
     1368108000000, 
     1368194400000 
    ], 
    [ 
     1368367200000, 
     1368540000000, 
     1368626400000, 
    ], 
    [ 
     1368712800000Ω 
    ] 

Więc w końcu, mam tablicę, z 3 tablicami wszystkich czasów. Próbowałem już wielu kawałków kodu, ale wszystko się psuje i nic nie jest warte zamieszczania tutaj. Każda pomoc będzie doceniona!

+2

Powinieneś opublikować jeden z tych _dziesięciu kawałków kodu_. –

+7

Powinniśmy głosować więcej za tego rodzaju dobrze sformatowane i dobrze wyjaśnione pytania! +1 –

+0

Twój przykład da Ci cztery tablice, ponieważ różnica między dwiema pierwszymi datami w drugiej macierzy to dwa dni. – Andreas

Odpowiedz

2

Poniższa metoda wykorzystuje .reduce() metody tablicy:

var arr = [1367848800000, 1367935200000, 1368021600000, 
      1368108000000, 1368194400000, 1368367200000, 
      1368540000000, 1368626400000, 1368712800000], 
    i = 0, 
    result = arr.reduce(function(stack, b) { 
     var cur = stack[i], 
      a = cur ? cur[cur.length-1] : 0; 

     if (b - a > 86400000) { 
      i++; 
     } 

     if (!stack[i]) 
      stack[i] = []; 

     stack[i].push(b); 

     return stack; 
    }, []); 

console.log(result); 

DEMO:http://jsfiddle.net/gbC8B/1/

+0

Działa perfekcyjnie! Wybrałem twoje, ponieważ wydawało się bardzo czyste i proste. Dziękuję Ci bardzo. – MichaelH

+0

@MichaelH Serdecznie zapraszamy! Zapomniałem wspomnieć, że tablica '.reduce()' może nie być obsługiwana przez * starsze * przeglądarki, a * MDN * sugeruje użycie [shim dla kompatybilności] (https://developer.mozilla.org/en-US/ docs/JavaScript/Reference/Global_Objects/Array/Reduce # Compatibility) (jeśli naprawdę tego potrzebujesz). – VisioN

+0

Na szczęście obsługujemy tylko nowoczesne przeglądarki. Twoje zdrowie. – MichaelH

1

Sth jak może to zrobić:

function sequentialize(dArr) { 
     dArr = Object.keys(dArr).slice().sort(); 
     var last; 
     var arrs = [[]]; 

     for (var i = 0, l = dArr.length; i < l; i++) { 
      var cur = new Date(); 
      cur.setTime(dArr[i]); 
      last = last || cur; 

      if (isNewSequence(cur, last)) { 
       arrs.push([]); 
      } 

      arrs[arrs.length - 1].push(cur.getTime()); //always push to the last index 
      last = cur; 
     } 


     return arrs; 


     function isNewSequence(a, b) { 
      if (a.getTime() - b.getTime() > (24 * 60 * 60 * 1000)) 
       return true; 
      return false; 
     } 
    } 

Teraz, jeśli zdać przykład Array/Object do funkcji sequentialize

var dates = { 
     1367848800000: true, 
     1367935200000: true, 
     1368021600000: true, 
     1368108000000: true, 
     1368194400000: true, 
     1368367200000: true, 
     1368540000000: true, 
     1368626400000: true, 
     1368712800000: true 
    }; 

    console.log(sequentialize(dates)); 

To daje następujący wynik

[ 
     [ 
      1367848800000, 
      1367935200000, 
      1368021600000, 
      1368108000000, 
      1368194400000 
     ], 
     [ 
      1368367200000 
     ], 
     [ 
      1368540000000, 
      1368626400000, 
      1368712800000 
     ] 
    ] 

To po prostu

  1. tworzy tablicę z datą kluczy

  2. sortuje je

  3. iteracyjnie do nich

  4. Jeżeli różnica prądu i Ostatni Data jest ważniejsza niż dzień

  5. push nową tablicę do tablicy Sekwencji

  6. Naciśnij bieżącą datę ostatniej tablicy w tablicy Sekwencji

    Demo na JSBin

Uwaga: Może trzeba zmienić funkcja isNewSequence w celu dopasowania do Twoich potrzeb

1
// Preconditions: singleArray contains the input array with each element corresponding to a time index. singleArray is sorted. 

var outputArray = new Array(); 
var stack = new Array(); 
var stackSize = 0; 

var i; 
for(i = 0; i < singleArray.length; i++) 
{ 
    // Get the last element on the stack 
    var lastElement = (stackSize == 0) ? 0 : stack.pop(); 

    // Compare to see if difference is one day 
    if(singleArray[i] - lastElement == 86400000) // 24 * 60 * 60 * 1000 
    { 
     // Dates are 1 day apart 
     if(lastElement != 0) stack.push(lastElement); 
     stack.push(singleArray[i]); 
     stackSize++; 
    } 
    else 
    { 
     if(lastElement != 0) stack.push(lastElement); 

     var tempQueue = new Array(); 
     while(stackSize > 0) 
     { 
      // Build up a new array containing consecutive days 
      // using a queue 
      tempQueue.push(stack.pop()); 
      stackSize--; 
     } 

     // Push the consecutive days onto the next place in the output array. 
     outputArray.push(tempQueue); 

     // Start a new group of consecutive dates 
     stack.push(singleArray[i]); 
     stackSize++; 
    } 

} 
+0

Niestety javascript nie ma metody podglądu, więc musimy wcisnąć ostatni element z powrotem na – ose

1

pokochałbyś tych zagadek. Dobre odpowiedzi dla wszystkich, oto moje bardziej jQueryskie podejście.

var datearray = { 
    1367848800000: true, 
    1367935200000: true, 
    1368021600000: true, 
    1368108000000: true, 
    1368194400000: true, 
    1368367200000: true, 
    1368540000000: true, 
    1368626400000: true, 
    1368712800000: true 
}; 

$(function() { 

    var result = dateSequences(datearray); 
} 

function dateSequences(array) { 
    // parse json object to array of keys 
    var keys = Object.keys(array); 
    // sort it up 
    keys = keys.sort(); 
    // convert them to dates 
    var dates = new Array(); 
    $.each(keys, function(i) { 
     dates.push(new Date(parseInt(keys[i]))); 
    }); 

    // now we have array of dates, search for sequential dates 
    var final = new Array(); 
    var prevdate = undefined; 
    var currentseq = 0;  
    $.each(dates, function(i, d) { 
     // undefined? 
     // first sequence 
     if (prevdate == undefined) { 
      final.push(new Array()); 
      final[currentseq].push(d); 
     } 
     else { 
      // compare if difference to current date in loop is greater than a day 
      var comp=new Date(); 
      comp.setDate(prevdate.getDate()+2); 
      // Advance sequence if it is 
      if (comp < d) { 
       currentseq++; 
       final[currentseq] = new Array(); 
      } 
      // Push the date to current sequence 
      final[currentseq].push(d);    
     } 
     // store previous 
     prevdate = d; 
    }); 

    return final; 
} 

Fiddle:

http://jsfiddle.net/f57Ah/1/

1

próbował tablica sort z forEach

var dates = [1367848800000, 1367935200000, 1368021600000, 
      1368108000000, 1368194400000, 1368367200000, 
      1368540000000, 1368626400000, 1368712800000]; 

var k = 0 , sorted = [[]]; 

dates.sort(function (a, b){ 

    return +a > +b ? 1 : +a == +b ? 0: -1; 
}) 
.forEach(function(v , i){ 

    var a = v,b = dates[i+1]||0; 

    sorted[k].push(+a); 

    if ((+b - +a) > 86400000) { 
      sorted[++k] = [] 
    } 
}); 

Później można je sortować według liczby

sorted.sort(function (a,b){ 
    return a.length > b.length ? -1: 1; 
}); 

Tablica zawiera pożądany wynik jsfiddle