miller/pkg/transformers/aaa_transformer_table.go
John Kerl f9afae491f
Add mlr rank verb (#2178)
* stats1: add rank accumulator (#383)

Adds `mlr stats1 -a rank` for standard competition ranking (1,2,2,4,...)
on pre-sorted data, most useful with -s for a rank on every record.

* stats1: make rank order-independent by default, add --rank-sorted opt-in fast path

The rank accumulator previously only compared each value to the immediately
preceding record, silently giving wrong ranks for non-adjacent duplicates
(e.g. unsorted input, or interleaved -g groups). Default to correctly
computing standard competition rank from all values seen so far
(order-independent, buffers values, same approach as percentile
accumulators). Add --rank-sorted for callers who can promise sorted input
and want the previous O(1)-space streaming behavior instead.

* Revert "stats1: make rank order-independent by default, add --rank-sorted opt-in fast path"

This reverts commit aa45a591fe.

* Revert "stats1: add rank accumulator (#383)"

This reverts commit 96deed048a.

* Add mlr rank verb (#383)

Reverts the earlier stats1 -a rank / --rank-sorted approach: stats1 is a
reduce verb (many records -> one summary record per group) and rank is a
per-record annotator, so it never fit cleanly there -- it needed stats1's
-s iterative-stats escape hatch just to be useful, plus a bolted-on
sorted/unsorted split.

mlr rank is a dedicated verb modeled on mlr fraction: -f fields to rank,
-g optional group-by, output field <f>_rank. By default it's a two-pass
algorithm (buffers input, like fraction does) giving standard competition
rank (1,2,2,4,...) that's correct regardless of input order. --sorted
opts into a single-pass, O(1)-space streaming alternative for callers who
can promise pre-sorted input (e.g. via 'mlr sort' first).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* Regenerate docs/man pages after merging main (sparkline verb)

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-07 17:35:18 -04:00

158 lines
3.2 KiB
Go

package transformers
import (
"fmt"
"os"
"strings"
"github.com/johnkerl/miller/v6/pkg/colorizer"
"github.com/johnkerl/miller/v6/pkg/lib"
)
var TRANSFORMER_LOOKUP_TABLE = []TransformerSetup{
AltkvSetup,
BarSetup,
BootstrapSetup,
CaseSetup,
CatSetup,
CheckSetup,
CleanWhitespaceSetup,
CountDistinctSetup,
CountSetup,
CountSimilarSetup,
CutSetup,
DecimateSetup,
DescribeSetup,
FillDownSetup,
FillEmptySetup,
FilterSetup,
FlattenSetup,
FormatValuesSetup,
FractionSetup,
GapSetup,
GrepSetup,
GroupBySetup,
GroupLikeSetup,
GsubSetup,
HavingFieldsSetup,
HeadSetup,
HistogramSetup,
JSONParseSetup,
JSONStringifySetup,
JoinSetup,
LabelSetup,
Latin1ToUTF8Setup,
LeastFrequentSetup,
MergeFieldsSetup,
MostFrequentSetup,
NestSetup,
NothingSetup,
PutSetup,
RankSetup,
RegularizeSetup,
RemoveEmptyColumnsSetup,
RenameSetup,
ReorderSetup,
RepeatSetup,
ReshapeSetup,
SampleSetup,
Sec2GMTDateSetup,
Sec2GMTSetup,
SeqgenSetup,
ShuffleSetup,
SkipTrivialRecordsSetup,
SortSetup,
SortWithinRecordsSetup,
SparklineSetup,
SparsifySetup,
SplitSetup,
SsubSetup,
Stats1Setup,
Stats2Setup,
StepSetup,
SubSetup,
SummarySetup,
SurvSetup,
TacSetup,
TailSetup,
TeeSetup,
TemplateSetup,
TopSetup,
UTF8ToLatin1Setup,
UnflattenSetup,
UniqSetup,
UnspaceSetup,
UnsparsifySetup,
}
func ShowHelpForTransformer(verb string) bool {
transformerSetup := LookUp(verb)
if transformerSetup != nil {
fmt.Println(colorizer.MaybeColorizeHelp(transformerSetup.Verb, true))
transformerSetup.UsageFunc(os.Stdout)
return true
}
return false
}
func ShowHelpForTransformerApproximate(searchString string) bool {
found := false
for _, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
if strings.Contains(transformerSetup.Verb, searchString) {
fmt.Println(colorizer.MaybeColorizeHelp(transformerSetup.Verb, true))
transformerSetup.UsageFunc(os.Stdout)
found = true
}
}
return found
}
func LookUp(verb string) *TransformerSetup {
for _, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
if transformerSetup.Verb == verb {
return &transformerSetup
}
}
return nil
}
// GetVerbNames returns all verb names, in table order, for use as
// shell-completion candidates (pkg/terminals/completion).
func GetVerbNames() []string {
verbNames := make([]string, len(TRANSFORMER_LOOKUP_TABLE))
for i, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
verbNames[i] = transformerSetup.Verb
}
return verbNames
}
func ListVerbNamesVertically() {
for _, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
fmt.Printf("%s\n", transformerSetup.Verb)
}
}
func ListVerbNamesAsParagraph() {
verbNames := make([]string, len(TRANSFORMER_LOOKUP_TABLE))
for i, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
verbNames[i] = transformerSetup.Verb
}
lib.PrintWordsAsParagraph(verbNames)
}
func UsageVerbs() {
separator := "================================================================"
for i, transformerSetup := range TRANSFORMER_LOOKUP_TABLE {
if i > 0 {
fmt.Println()
}
fmt.Printf("%s\n", separator)
lib.InternalCodingErrorIf(transformerSetup.UsageFunc == nil)
fmt.Println(colorizer.MaybeColorizeHelp(transformerSetup.Verb, true))
transformerSetup.UsageFunc(os.Stdout)
}
fmt.Printf("%s\n", separator)
}