2016-04-18 9 views
0

Lasst uns sagen, dass ich eine Reihe von jeder feste Länge haben, dh es 3 sein könnte, 5, 7 ... bis 30.neues Objekt holen täglich von Array

Wie kann ich einen Algorithmus so zu erzeugen, dass, wenn ich wählen ein Element aus dem Array, sollte es an zwei aufeinanderfolgenden Tagen nicht jeden Tag denselben Item-Index auswählen.

Hinweis: Ich habe nicht die Möglichkeit zu speichern, was am Vortag ausgewählt wurde.

Zum Beispiel wenn mein Array ist [ "a", "b", "c", "d", "e", "f"]

gültiges Ergebnis wäre ["a", "b", "c", "d", "e", "f", "d", "a", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f"]

Ungültiges Ergebnis würde

["a", "b", "c", "d", "e", "f", "a", "b", "b", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f"]

Notiere die konsekutiven b in oben

sein

Ein ideales Ergebnis wäre: wo das ganze Array nach dem Ende der Länge perfekt gedreht wird.

["a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f", "a", "b", "c", "d", "e", "f"]

+0

Wenn Sie es wollen, den ganzen Tag das gleiche Ergebnis erhalten, unabhängig davon, wie oft sie aufgerufen wird, dann würde ich vorschlagen, den Tag des Monats mit als ein Indexer irgendeiner Art. Kochen Sie das herunter, damit es zu Ihrem Array passt, und Sie haben standardmäßig ein tägliches, einzigartiges und inkrementierendes Ergebnis. – Antiga

+0

Haben Sie Zugriff auf die Tagesnummer? Sie könnten einfach die Tag-Zahl modulo als Anzahl der Elemente im Array als Index eines Elements verwenden, das ausgewählt werden soll. Andernfalls könnten Sie das ausgewählte Element mit dem Element mit dem Index '0' austauschen und immer Elemente aus dem Bereich '[1, n - 1] 'auswählen, so dass Sie nie das vorherige Element auswählen, wie es an der Position 0 –

+0

ist möchte eine (Pseudo-) Zufallssequenz und keinen Index folgen. Recht? jeden Tag einen (und denselben) Index ausgewählt. Wie lange sollte diese Sequenz dauern (wie viele Tage/Monate/Jahre)? und müssen Sie in der Lage sein, Werte aus der Vergangenheit auszuwählen? – Thomas

Antwort

1

Versuchen mod (%) unter Verwendung von auf diese Weise die Zahl kann nie die Array-Länge überschreiten. Demo:

var array = ["a", "b", "c", "d", "e", "f"]; 
var output = []; 
for (var day = 1; day < 365; day++) { 
    output.push(array[day % array.length]) 
} 
console.log(output); 
1
var d = new Date(); 
var n = d.getDay(); 
var chr = String.fromCharCode(97 + n); 

Run dies jeden Tag den nächsten Wert in der Sequenz zu erzeugen.

So wird Ihre Sequenz:

a, b, c, d, e, f, g

1

Dies ist sehr einfach mit getDate zu erreichen, die den aktuellen Tag des Monats zurückgibt (1-31 je nach Monat). Durch die Kombination mit dem Modulo-Operator wird sichergestellt, dass Sie immer einen gültigen Artikel in nicht aufeinanderfolgender Reihenfolge erhalten.

function log(msg) { 
 
    document.querySelector('pre').innerHTML += msg + '\n'; 
 
} 
 

 
function logItem(items, date) { 
 
    var index = (date.getDate() - 1) % items.length; 
 
    var item = items[index]; 
 
    log(date.toDateString() + ' : ' + item); 
 
} 
 

 
function addDay(date) { 
 
    date.setDate(date.getDate() + 1); 
 
} 
 
var items = ['a', 'b', 'c', 'd', 'e', 'f']; 
 
var day = new Date(2016, 0, 1); 
 
for (var i = 0; i < items.length * 3; i++) { 
 
    logItem(items, day); 
 
    addDay(day); 
 
}
<pre></pre>

Es gibt ein Problem mit dieser exakten Umsetzung: Es ist möglich, dass das Ende des Monats den gleichen relativen Wert als die ersten des Monats zu haben.

function log(msg) { 
 
    document.querySelector('pre').innerHTML += msg + '\n'; 
 
} 
 

 
function logItem(items, date) { 
 
    var index = (date.getDate() - 1) % items.length; 
 
    var item = items[index]; 
 
    log(date.toDateString() + ' : ' + item); 
 
} 
 

 
function addDay(date) { 
 
    date.setDate(date.getDate() + 1); 
 
} 
 
var items = ['a', 'b', 'c', 'd', 'e', 'f']; 
 
var day = new Date(2016, 0, 30); 
 
for (var i = 0; i < 4; i++) { 
 
    logItem(items, day); 
 
    addDay(day); 
 
}
<pre></pre>

Um dies zu umgehen, können Sie determine how many days are in the month können, festzustellen, ob Ihre Start- und Zielindizes gleich sind und man sich ändern, wenn sie sind. Wie Sie einen alternativen Wert auswählen, bleibt Ihnen überlassen.

function log(msg) { 
 
    document.querySelector('pre').innerHTML += msg + '\n'; 
 
} 
 

 
function logItem(items, date) { 
 
    // --- 
 
    var daysInMonth = getDays(date); 
 
    var day = date.getDate(); 
 
    var index = (day - 1) % items.length; 
 
    if (day === daysInMonth && (day - 1) % items.length === 0) { 
 
    // Change to a different item 
 
    index = Math.floor(Math.random() * (items.length - 3)) + 2; 
 
    } 
 
    // --- 
 
    var item = items[index]; 
 
    log(date.toDateString() + ' : ' + item); 
 
} 
 

 
function getDays(date) { 
 
    return new Date(date.getYear(), date.getMonth() + 1, 0).getDate(); 
 
} 
 

 
function addDay(date) { 
 
    date.setDate(date.getDate() + 1); 
 
} 
 
var items = ['a', 'b', 'c', 'd', 'e', 'f']; 
 
var day = new Date(2016, 0, 30); 
 
for (var i = 0; i < 4; i++) { 
 
    logItem(items, day); 
 
    addDay(day); 
 
}
<pre></pre>

1

habe ich eine Lösung, die die Modulo operater mit: %. Nicht sicher, ob dies genau das ist, was Sie wollen, aber es scheint richtig zu funktionieren.

Sie könnten das vermutlich in eine Funktion einfügen oder es anzeigen, wie Sie möchten.

0

Probieren Sie etwas wie dieses

var a = ["a", "b", "c", "d", "e", "f"], 
 
    b = [], 
 
    random; 
 

 
var i = function(val) { 
 
    random = val[Math.floor(Math.random() * val.length)]; 
 
    (random != b[b.length - 1]) ? b.push(random): b.push('duplicate'); 
 
    console.log(b); 
 
} 
 

 
setInterval(() => { 
 
    i(a) 
 
}, 1000);

+0

Dies berücksichtigt den Tag überhaupt nicht. Wenn dieser Algorithmus während verschiedener Durchläufe des Programms an aufeinanderfolgenden Tagen ausgeführt wurde, könnte er die gleiche Ausgabe an beiden Tagen erzeugen. –

+0

@Mike C Sie haben Recht, ich habe 'setInterval' nur für Demozwecke verwendet –