2013-09-26 6 views
5

Ho letto molte delle risposte qui come ho potuto trovare che aveva titoli che consideravo abbastanza vicino al mio problema da esaminare. Non ho visto nessuno che avesse il mio problema preciso, quindi sto facendo una domanda che spero solo che io sia ignorante di un semplice fatto.Lua Tabella ordinamento 2 confronta

Sto provando a codificare una tabella che registra HP (int) e la distanza (booleana) e quindi ordinare da HP con solo quelli in Gamma nella parte superiore.

local tableTest = { 
    {hp = 64, range = true, name="Frank"}, 
    {hp = 100, range = true, name="Joe"}, 
    {hp = 2, range = false, name="Jim"}, 
    {hp = 76, range = true, name="Tim"}, 
    {hp = 17, range = false, name="Jill"}, 
    {hp = 16, range = true, name="Phillip"}, 
} 

-- Sort by HP and Range to find lowest Unit in Range. 
table.sort(tableTest, function(x,y) return x.hp < y.hp and x.range end) 

for i=1, #tableTest do print(tableTest[i].name, tableTest[i].hp) end 

L'uscita di questo è:

Phillip 16 
Jim  2 
Frank 64 
Jill 17 
Tim  76 
Joe  100 

L'uscita mi aspettavo da questo sarebbe:

Phillip 16 
Frank 64 
Tim  76 
Joe  100 
Jim  2 
Jill 17 

io prego che questo è solo un equivoco da parte di come la mia table.sort funziona con controlli multipli come questo (ho pensato che fosse più vicino a come dichiari una variabile come questa).

modificare Ulteriori informazioni - Se cambio l'ordine di dove i range=false indici si trovano nella tabella, le modifiche di uscita così (ancora errata). I valori si suddividono in indici diversi dopo l'ordinamento.

risposta

4

In base alla descrizione, la funzione dell'ordine deve confrontare prima range, quindi confrontare hp.

Forse c'è una versione più breve, ma questa funziona sicuramente e la logica è chiara.

+0

ty ty! Penso di aver capito cosa ho sbagliato. Stavo pensando in termini di return true's only. Quindi, se devo comprenderlo correttamente, voglio solo assicurarmi che sto leggendo questo bene. Per prima cosa controlliamo che entrambi gli intervalli siano veri, quindi ordiniamo per HP. Se entrambi gli intervalli non sono veri, vedremo se la x ha un intervallo reale, quindi restituisce true, altrimenti vediamo se y ha l'intervallo e restituisce false. Se entrambi sono falsi, allora ordiniamo quelli al di fuori dell'intervallo di HP. Dove ho fallito nei miei test era il elseif y.range return false. Facciamo questo per aiutare a valutare correttamente il valore? – Bubba911

+0

@ Bubba911 In questo caso, 'x.range' è' false' mentre 'y.range' è' true', quindi 'x' dovrebbe essere dopo' y' indipendentemente dal valore di 'hp'. –

+0

Ty per aver chiarito che :) La mia mente si stava ancora avvolgendo attorno ad essa. Dopo averlo detto a voce alta a me stesso un paio di volte, quello che hai detto è ciò che ho inventato (dopo la pubblicazione). Quindi è bello sentire che la mia comprensione è corretta! Grazie ancora, spero che tu abbia un gran bel giorno, signore. – Bubba911

0

Hai già una risposta a questa domanda, ma penso che valga la pena aggiungere un altro qui che spiega come puoi ragionare su questa logica più facilmente. Le idee presentate qui sono davvero indipendenti dal linguaggio.

Lo scopo di fornire una funzione di confronto è davvero di rispondere a una domanda: Se x venire prima y? Un altro modo per porre la stessa domanda è: x hanno una precedenza più alta quindi y? Spesso lo si implementa con le stesse proprietà di ordinamento dell'operatore <.

Così la vostra funzione dovrebbe restituire truesolo se x sicuramente precede y. Nel tuo caso, per prima cosa stai selezionando il campo range e se entrambi risultano essere true quindi utilizzare il campo hp come "tie-breaker".

È possibile costruire una tabella di verità qui per aiutarvi a trovare il modo più conciso per esprimere la condizione logica che produce il comportamento che stai cercando:

x | y | x before y? 
------------------------- 
    T | T | x.hp < y.hp 
    T | F | T 
    F | T | F 
    F | F | F 

tuo stato originale x.hp < y.hp and x.range è vicino, ma non del tutto corretto per tutti i casi possibili.

sopra vediamo che se x è falso allora il risultato finale è anche falsa indipendentemente da ciò y è. Quindi y viene considerato solo quando x è vero. Infine, per evitare l'avvertimento di una falsa condizione nel cortocircuito logico in lua vorremmo che x.hp < y.hp fosse alla fine dell'espressione logica. Quindi, la condizione logica che stai cercando è:

return x.range and (not y.range or x.hp < y.hp)