使用 TCL 或 sqlite 从带有符号的列表中获取前 x 值(独立于符号)
Get the top x values (independent of the sign) from a list with sign using TCL or sqlite
有一个包含正数和负数的列表,目标是根据数字的 abs 值获取前 x 值,但带有符号。例如
set Input [list -3122.0 -1618.0 -1551.0 -894.2 296.4 2226.0 1855.0 1318.0 872.5 2004.0 2026.0 2828.0 ]
输出应该是(当只请求前 10 个时):
Output [ list -3122.0 2828.0 2226.0 2026.0 2004.0 1855.0 -1618.0 -1551.0 1318.0 -894.2 ]
我使用下面的代码,
set ForceIDsPosetiv [ DB eval { SELECT Forcec FROM MaxForces WHERE Force > 0} ]
set ForceIDsNegativ [ DB eval { SELECT Forcec FROM MaxForces WHERE Force < 0} ]
set ForceIDsPosetiv [lsort -decreasing -real $ForceIDsPosetiv]
set ForceIDsNegativ [lsort -increasing -real $ForceIDsNegativ]
set SortedForcList ""
for {set row 0 } { $row <= 9 } {incr row} {
set firstForcePos [lindex $ForceIDsPosetiv 0]
set firstForceNeg [lindex $ForceIDsNegativ 0]
if { $firstForcePos == "" } {
lappend SortedForcList $firstForceNeg
set ForceIDsNegativ [lreplace $ForceIDsNegativ 0 0]
} else {
if { $firstForceNeg == "" } {
lappend SortedForcList $firstForcePos
set ForceIDsPosetiv [lreplace $ForceIDsPosetiv 0 0]
} else {
if { abs($firstForcePos) > abs($firstForceNeg) } {
lappend SortedForcList $firstForcePos
set ForceIDsPosetiv [lreplace $ForceIDsPosetiv 0 0]
} else {
lappend SortedForcList $firstForceNeg
set ForceIDsNegativ [lreplace $ForceIDsNegativ 0 0]
}
}
}
}
但我觉得有一种更有效的方法可以解决这个问题。你有什么建议吗?如您所见,我一开始使用的是 sqlite 数据库。 table 只有一列包含所有力。因此,也将不胜感激使用 sqlite 的解决方案。
我不知道 TCL,但 SQL 查询类似于:
SELECT Forcec
FROM Maxforces
ORDER BY abs(Forcec) DESC
LIMIT 10
想法是按数字的绝对值降序排序(所以最大的在前),但是return原始数字。
编辑:现在我知道了 TCL:
set Input [list -3122.0 -1618.0 -1551.0 -894.2 296.4 2226.0 1855.0 1318.0 872.5 2004.0 2026.0 2828.0 ]
proc abscomp {a b} {
set a [::tcl::mathfunc::abs $a]
set b [::tcl::mathfunc::abs $b]
if {$a < $b} {
return -1
} elseif { $a > $b } {
return 1
} else {
return 0
}
}
set Output [lrange [lsort -decreasing -command abscomp $Input] 0 9]
有一个包含正数和负数的列表,目标是根据数字的 abs 值获取前 x 值,但带有符号。例如
set Input [list -3122.0 -1618.0 -1551.0 -894.2 296.4 2226.0 1855.0 1318.0 872.5 2004.0 2026.0 2828.0 ]
输出应该是(当只请求前 10 个时):
Output [ list -3122.0 2828.0 2226.0 2026.0 2004.0 1855.0 -1618.0 -1551.0 1318.0 -894.2 ]
我使用下面的代码,
set ForceIDsPosetiv [ DB eval { SELECT Forcec FROM MaxForces WHERE Force > 0} ]
set ForceIDsNegativ [ DB eval { SELECT Forcec FROM MaxForces WHERE Force < 0} ]
set ForceIDsPosetiv [lsort -decreasing -real $ForceIDsPosetiv]
set ForceIDsNegativ [lsort -increasing -real $ForceIDsNegativ]
set SortedForcList ""
for {set row 0 } { $row <= 9 } {incr row} {
set firstForcePos [lindex $ForceIDsPosetiv 0]
set firstForceNeg [lindex $ForceIDsNegativ 0]
if { $firstForcePos == "" } {
lappend SortedForcList $firstForceNeg
set ForceIDsNegativ [lreplace $ForceIDsNegativ 0 0]
} else {
if { $firstForceNeg == "" } {
lappend SortedForcList $firstForcePos
set ForceIDsPosetiv [lreplace $ForceIDsPosetiv 0 0]
} else {
if { abs($firstForcePos) > abs($firstForceNeg) } {
lappend SortedForcList $firstForcePos
set ForceIDsPosetiv [lreplace $ForceIDsPosetiv 0 0]
} else {
lappend SortedForcList $firstForceNeg
set ForceIDsNegativ [lreplace $ForceIDsNegativ 0 0]
}
}
}
}
但我觉得有一种更有效的方法可以解决这个问题。你有什么建议吗?如您所见,我一开始使用的是 sqlite 数据库。 table 只有一列包含所有力。因此,也将不胜感激使用 sqlite 的解决方案。
我不知道 TCL,但 SQL 查询类似于:
SELECT Forcec
FROM Maxforces
ORDER BY abs(Forcec) DESC
LIMIT 10
想法是按数字的绝对值降序排序(所以最大的在前),但是return原始数字。
编辑:现在我知道了 TCL:
set Input [list -3122.0 -1618.0 -1551.0 -894.2 296.4 2226.0 1855.0 1318.0 872.5 2004.0 2026.0 2828.0 ]
proc abscomp {a b} {
set a [::tcl::mathfunc::abs $a]
set b [::tcl::mathfunc::abs $b]
if {$a < $b} {
return -1
} elseif { $a > $b } {
return 1
} else {
return 0
}
}
set Output [lrange [lsort -decreasing -command abscomp $Input] 0 9]