diff --git a/README.md b/README.md index 4969e54..50b902f 100644 --- a/README.md +++ b/README.md @@ -440,7 +440,25 @@ For the input string 'Hello World!': - `6,0,7`: WHo - `-6:`: World! - `-6:,:5`: World!Hello +## Subset +Subset allows for a [Python like](https://learnpython.com/blog/substring-of-string-python/) subset selection of its inputs. +For a filter with parents with these results: +- First parent + - `zero` + - `one` +- Second parent + - `two` +- Third parent + - `three` + - `four` +Then: +- `0`: `zero` +- `-1`: `four` +- `0,3`: `zero`, `three` +- `2:4`: `two`, `three` +- `-2:`: `three`, `four` +- `:-2`: `zero`, `one`, `two`, `three` ## Contains Inputs pass if they contain the given regex. diff --git a/web/scraping.go b/web/scraping.go index d01b5c7..afdb028 100644 --- a/web/scraping.go +++ b/web/scraping.go @@ -738,10 +738,13 @@ func getFilterResultSubstring(filter *Filter) { } } else { pos, err := strconv.ParseInt(substring, 10, 32) - if err != nil || pos < 0 { + if err != nil { filter.Log("Could not parse: '", substring, "'") return } + if pos < 0 { + pos = int64(len(asRunes)) + pos + } if pos < 0 || pos >= int64(len(asRunes)) { filter.Log("Out of bounds:", pos) continue @@ -826,10 +829,13 @@ func getFilterResultSubset(filter *Filter) { } } else { pos, err := strconv.ParseInt(substring, 10, 32) - if err != nil || pos < 0 { + if err != nil { filter.Log("Could not parse: '", substring, "'") return } + if pos < 0 { + pos = int64(len(results)) + pos + } if pos < 0 || pos >= int64(numResults) { filter.Log("Out of bounds:", pos) continue diff --git a/web/scraping_test.go b/web/scraping_test.go index 3fb4e7d..e3f5d69 100644 --- a/web/scraping_test.go +++ b/web/scraping_test.go @@ -389,6 +389,8 @@ func TestFilterSubstring(t *testing.T) { }{ {"0123456789", "0", "0"}, {"0123456789", "9", "9"}, + {"0123456789", "-1", "9"}, + {"0123456789", "0,9", "09"}, {"0123456789", "0:3", "012"}, {"0123456789", ":3", "012"}, @@ -439,7 +441,6 @@ func TestFilterSubstringOutOfBounds(t *testing.T) { {"01234", "0:8"}, {"01234", ":-6"}, {"01234", "-6:"}, - {"01234", "-1"}, {"01234", "6"}, } @@ -470,10 +471,11 @@ func TestFilterSubset(t *testing.T) { }{ {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "0", []string{"zero"}}, {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "6", []string{"six"}}, - {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "-1", []string{}}, + {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "-1", []string{"six"}}, {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "7", []string{}}, {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "0,3,6", []string{"zero", "three", "six"}}, + {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "0,3,-2", []string{"zero", "three", "five"}}, {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "0,2:5,6", []string{"zero", "two", "three", "four", "six"}}, {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "3:6", []string{"three", "four", "five"}}, @@ -481,6 +483,8 @@ func TestFilterSubset(t *testing.T) { {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "0:7", []string{"zero", "one", "two", "three", "four", "five", "six"}}, {[]string{"zero", "one", "two", "three", "four", "five", "six"}, ":7", []string{"zero", "one", "two", "three", "four", "five", "six"}}, {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "0:", []string{"zero", "one", "two", "three", "four", "five", "six"}}, + {[]string{"zero", "one", "two", "three", "four", "five", "six"}, "-2:", []string{"five", "six"}}, + {[]string{"zero", "one", "two", "three", "four", "five", "six"}, ":-2", []string{"zero", "one", "two", "three", "four"}}, } for _, test := range tests {