使用 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]