Sort a list of object identifiers: Difference between revisions
Content added Content deleted
(+Sather) |
|||
Line 1,595: | Line 1,595: | ||
} |
} |
||
</lang> |
</lang> |
||
=={{header|Nim}}== |
|||
=== OID as distinct string === |
|||
Nim allows to define distinct types. As OID are peculiar strings, defining them as distinct strings seems a good idea. We have to define a specific comparison procedure and that’s all. Here is the code: |
|||
<lang Nim>import algorithm, sequtils, strutils |
|||
type OID = distinct string |
|||
# Borrow the `$` procedure from the base string type. |
|||
proc `$`(oid: OID): string {.borrow.} |
|||
template toSeqInt(oid: OID): seq[int] = |
|||
## Convert an OID into a sequence of integers. |
|||
oid.string.split('.').map(parseInt) |
|||
proc oidCmp(a, b: OID): int = |
|||
## Compare two OIDs. Return 0 if OIDs are equal, -1 if the first is |
|||
## less than the second, +1 is the first is greater than the second. |
|||
let aseq = a.toSeqInt |
|||
let bseq = b.toSeqInt |
|||
for i in 0..<min(aseq.len, bseq.len): |
|||
result = cmp(aseq[i], bseq[i]) |
|||
if result != 0: return |
|||
result = cmp(aseq.len, bseq.len) |
|||
when isMainModule: |
|||
const OIDS = [OID"1.3.6.1.4.1.11.2.17.19.3.4.0.10", |
|||
OID"1.3.6.1.4.1.11.2.17.5.2.0.79", |
|||
OID"1.3.6.1.4.1.11.2.17.19.3.4.0.4", |
|||
OID"1.3.6.1.4.1.11150.3.4.0.1", |
|||
OID"1.3.6.1.4.1.11.2.17.19.3.4.0.1", |
|||
OID"1.3.6.1.4.1.11150.3.4.0"] |
|||
for oid in OIDS.sorted(oidCmp): |
|||
echo oid</lang> |
|||
Note that as the type is distinct, we have to borrow the procedure `$` to the string type in order to print OID values. |
|||
{{out}} |
|||
<pre>1.3.6.1.4.1.11.2.17.5.2.0.79 |
|||
1.3.6.1.4.1.11.2.17.19.3.4.0.1 |
|||
1.3.6.1.4.1.11.2.17.19.3.4.0.4 |
|||
1.3.6.1.4.1.11.2.17.19.3.4.0.10 |
|||
1.3.6.1.4.1.11150.3.4.0 |
|||
1.3.6.1.4.1.11150.3.4.0.1</pre> |
|||
=== OID as composite object === |
|||
The previous method is elegant but not very efficient. Indeed, every time a comparison is done, two conversions to a sequence of integers are done. And when sorting an array of OIDs, the same conversion is done several time. |
|||
To avoid this, we can define OID as a composite object type containing a string value and a list of integers to use for the comparisons. The code is not really more complicated, only arguably less elegant as we have to create the OIDs using the procedure “initOID”. |
|||
<lang Nim>import algorithm, sequtils, strutils |
|||
type OID = object |
|||
value: string |
|||
list: seq[int] |
|||
proc initOID(s: string): OID = |
|||
OID(value: s, list: s.split('.').map(parseInt)) |
|||
proc `$`(oid: OID): string = |
|||
oid.value |
|||
proc oidCmp(a, b: OID): int = |
|||
## Compare two OIDs. Return 0 if OIDs are equal, -1 if the first is |
|||
## less than the second, +1 is the first is greater than the second. |
|||
for i in 0..<min(a.list.len, b.list.len): |
|||
result = cmp(a.list[i], b.list[i]) |
|||
if result != 0: return |
|||
result = cmp(a.list.len, b.list.len) |
|||
when isMainModule: |
|||
const OIDS = [initOID("1.3.6.1.4.1.11.2.17.19.3.4.0.10"), |
|||
initOID("1.3.6.1.4.1.11.2.17.5.2.0.79"), |
|||
initOID("1.3.6.1.4.1.11.2.17.19.3.4.0.4"), |
|||
initOID("1.3.6.1.4.1.11150.3.4.0.1"), |
|||
initOID("1.3.6.1.4.1.11.2.17.19.3.4.0.1"), |
|||
initOID("1.3.6.1.4.1.11150.3.4.0")] |
|||
for oid in OIDS.sorted(oidCmp): |
|||
echo oid</lang> |
|||
{{out}} |
|||
Same as with the previous method. |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |