jointable -n vergleicht Schlüssel als Zahlen, Review Punkt 9 abgeschlossen
This commit is contained in:
@@ -42,6 +42,7 @@ folgen [Semantic Versioning](https://semver.org/lang/de/). Die Version steht in
|
|||||||
- Tabellen, Indexdateien und `substitute` werden über eine temporäre Datei mit `rename` geschrieben; ein Abbruch lässt die alte Datei statt einer halben neuen.
|
- Tabellen, Indexdateien und `substitute` werden über eine temporäre Datei mit `rename` geschrieben; ein Abbruch lässt die alte Datei statt einer halben neuen.
|
||||||
- `index -mb` und `-mi` sortieren nach dem Schlüssel ohne umgebende Leerzeichen, so wie `search` vergleicht.
|
- `index -mb` und `-mi` sortieren nach dem Schlüssel ohne umgebende Leerzeichen, so wie `search` vergleicht.
|
||||||
- `sorttable -r` kehrte auch die Reihenfolge gleicher Schlüssel um; sie bleibt jetzt erhalten.
|
- `sorttable -r` kehrte auch die Reihenfolge gleicher Schlüssel um; sie bleibt jetzt erhalten.
|
||||||
|
- `jointable -n` wurde stillschweigend ignoriert. Wie in der Man-Page vergleicht es die Schlüssel jetzt als Zahlen (`01`, `1` und ` 1.0` passen zusammen).
|
||||||
- Spaltennamen, die `justify` mit Leerzeichen aufgefüllt hat, wurden nicht mehr gefunden: `column Name` lieferte eine leere Spalte, `index` brach ab. Leerraum um die Namen im Kopf zählt jetzt nicht mehr.
|
- Spaltennamen, die `justify` mit Leerzeichen aufgefüllt hat, wurden nicht mehr gefunden: `column Name` lieferte eine leere Spalte, `index` brach ab. Leerraum um die Namen im Kopf zählt jetzt nicht mehr.
|
||||||
|
|
||||||
## [0.7.0] - 2026-10-12
|
## [0.7.0] - 2026-10-12
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ sind nach dem Handbuch neu geschrieben.
|
|||||||
mise trust # einmal nach dem Clone: mise.toml freigeben
|
mise trust # einmal nach dem Clone: mise.toml freigeben
|
||||||
mise install # Ruby 3.4
|
mise install # Ruby 3.4
|
||||||
mise run install # legt die Symlinks row, column, total ... in bin/ an
|
mise run install # legt die Symlinks row, column, total ... in bin/ an
|
||||||
mise run test # 131 Tests und die Beispiele aus dem Handbuch
|
mise run test # 132 Tests und die Beispiele aus dem Handbuch
|
||||||
```
|
```
|
||||||
|
|
||||||
Ohne `mise trust` brechen in einem frisch geklonten Ordner alle `mise`-Befehle ab.
|
Ohne `mise trust` brechen in einem frisch geklonten Ordner alle `mise`-Befehle ab.
|
||||||
|
|||||||
+10
-4
@@ -67,10 +67,16 @@ gelesen), 3 (Fehler als eine Zeile, `RDB_DEBUG=1` für den Backtrace), 4 (`EDITO
|
|||||||
Argumenten, Editorfehler wird gemeldet), 5 (Satz wird in jedem Fall zurückgeschrieben),
|
Argumenten, Editorfehler wird gemeldet), 5 (Satz wird in jedem Fall zurückgeschrieben),
|
||||||
6 (`Rdb.check_cells!`), 7 (`Rdb.write_file`: temporäre Datei plus `rename`) und 8
|
6 (`Rdb.check_cells!`), 7 (`Rdb.write_file`: temporäre Datei plus `rename`) und 8
|
||||||
(Sortierschlüssel ohne Leerzeichen) sind behoben, jeweils mit Test.
|
(Sortierschlüssel ohne Leerzeichen) sind behoben, jeweils mit Test.
|
||||||
Bei 9 ist nur `sorttable -r` behoben. Bewusst offen: `-nrf` gilt global (so beschreibt es
|
|
||||||
das Handbuch), `jointable -n` ist unklar spezifiziert, `1e3` als Zahl und die Zeile aus
|
Bei 9 sind `sorttable -r` (stabil) und `jointable -n` (Schlüssel als Zahlen, wie in der
|
||||||
leeren Zellen als „gelöscht“ sind Eigenheiten des Formats. Bei 8 bleibt `-x` (Faltung) beim
|
Man-Page) behoben. Bleibt so (Entscheidung 2026-10-30):
|
||||||
Index ohne Entsprechung in der Suche offen.
|
- `-nrf` gilt für alle Spalten: laut Man-Page reicht `sorttable` die Optionen an `sort`
|
||||||
|
weiter, Optionen pro Spalte gibt es im Original nicht.
|
||||||
|
- `1e3` ist keine Zahl: sonst würden Spalten mit Codes wie `2E5` numerisch.
|
||||||
|
- Eine Zeile aus lauter leeren Zellen gilt als gelöscht: so arbeitet `delete` im Format.
|
||||||
|
|
||||||
|
Offen bei 8: `index -x` (gefaltet) hat in `search` ohne `-x` kein Gegenstück, weil die
|
||||||
|
`.i`-Datei die Faltung nicht vermerkt. Das bräuchte eine Markierung im Indexkopf.
|
||||||
|
|
||||||
## Verbesserungspotential
|
## Verbesserungspotential
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ end
|
|||||||
|
|
||||||
Rdb.register('jointable', 'Join two tables into one where keys match',
|
Rdb.register('jointable', 'Join two tables into one where keys match',
|
||||||
'jointable [-a[1|2]] [-j[1|2] column]... [-n] [-] table1 [table2]') do |args|
|
'jointable [-a[1|2]] [-j[1|2] column]... [-n] [-] table1 [table2]') do |args|
|
||||||
all1 = all2 = false
|
all1 = all2 = numeric = false
|
||||||
k1 = k2 = nil
|
k1 = k2 = nil
|
||||||
files = []
|
files = []
|
||||||
until args.empty?
|
until args.empty?
|
||||||
@@ -108,7 +108,7 @@ Rdb.register('jointable', 'Join two tables into one where keys match',
|
|||||||
when '-j' then k1 = k2 = args.shift
|
when '-j' then k1 = k2 = args.shift
|
||||||
when '-j1' then k1 = args.shift
|
when '-j1' then k1 = args.shift
|
||||||
when '-j2' then k2 = args.shift
|
when '-j2' then k2 = args.shift
|
||||||
when '-n' then nil
|
when '-n' then numeric = true
|
||||||
else files << a
|
else files << a
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -119,13 +119,15 @@ Rdb.register('jointable', 'Join two tables into one where keys match',
|
|||||||
i1 = k1 ? t1.index_of(k1) : 0
|
i1 = k1 ? t1.index_of(k1) : 0
|
||||||
i2 = k2 ? t2.index_of(k2) : 0
|
i2 = k2 ? t2.index_of(k2) : 0
|
||||||
keep2 = (0...t2.head.size).to_a - [i2]
|
keep2 = (0...t2.head.size).to_a - [i2]
|
||||||
|
# -n compares keys as numbers: 01, 1 and " 1.0" are the same key
|
||||||
|
key = ->(v) { numeric && numeric?(v) ? Rdb.decimal(v) : v }
|
||||||
by_key = Hash.new { |h, k| h[k] = [] }
|
by_key = Hash.new { |h, k| h[k] = [] }
|
||||||
t2.rows.each { |r| by_key[r[i2]] << r }
|
t2.rows.each { |r| by_key[key.(r[i2])] << r }
|
||||||
used = {}
|
used = {}
|
||||||
out = []
|
out = []
|
||||||
t1.rows.each do |r|
|
t1.rows.each do |r|
|
||||||
if (m = by_key[r[i1]]).any?
|
if (m = by_key.fetch(key.(r[i1]), [])).any?
|
||||||
used[r[i1]] = true
|
used[key.(r[i1])] = true
|
||||||
m.each { |r2| out << r + keep2.map { |i| r2[i] } }
|
m.each { |r2| out << r + keep2.map { |i| r2[i] } }
|
||||||
elsif all1
|
elsif all1
|
||||||
out << r + [''] * keep2.size
|
out << r + [''] * keep2.size
|
||||||
@@ -133,7 +135,7 @@ Rdb.register('jointable', 'Join two tables into one where keys match',
|
|||||||
end
|
end
|
||||||
if all2
|
if all2
|
||||||
t2.rows.each do |r2|
|
t2.rows.each do |r2|
|
||||||
next if used[r2[i2]]
|
next if used[key.(r2[i2])]
|
||||||
|
|
||||||
blank = [''] * t1.head.size
|
blank = [''] * t1.head.size
|
||||||
blank[i1] = r2[i2]
|
blank[i1] = r2[i2]
|
||||||
|
|||||||
@@ -961,3 +961,13 @@ class ExactnessTest < RdbCase
|
|||||||
assert_equal 'v500', data_obj.row_at(data_obj.rows.last.from).cells[1]
|
assert_equal 'v500', data_obj.row_at(data_obj.rows.last.from).cells[1]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class JoinNumericTest < RdbCase
|
||||||
|
def test_jointable_n_matches_keys_as_numbers
|
||||||
|
write('j1', "K\tA\n-\t-\n01\tx\n 2\ty\n3\tz\n")
|
||||||
|
write('j2', "K\tB\n-\t-\n1\tp\n2.0\tq\n")
|
||||||
|
assert_empty data(rdb('jointable', 'j1', 'j2'))
|
||||||
|
assert_equal [%w[01 x p], [' 2', 'y', 'q']], data(rdb('jointable', '-n', 'j1', 'j2'))
|
||||||
|
assert_equal 3, data(rdb('jointable', '-n', '-a1', 'j1', 'j2')).size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user