From 348fa6aae1bb1b7f2ffdf12ef7e2b09bcb54b4b3 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 12 Oct 2023 16:36:08 +0200 Subject: [PATCH] ExtractSubIndexLists now allows non-sequential elements --- properties.go | 47 ++++++++++++++++++++++++++++++++++++---------- properties_test.go | 38 +++++++++++++++---------------------- 2 files changed, 52 insertions(+), 33 deletions(-) diff --git a/properties.go b/properties.go index b7cccb6..216fdee 100644 --- a/properties.go +++ b/properties.go @@ -76,6 +76,8 @@ import ( "reflect" "regexp" "runtime" + "sort" + "strconv" "strings" "unicode/utf8" @@ -630,6 +632,9 @@ func (m *Map) ExtractSubIndexSets(root string) []*Map { // "tre.discovery.required.1": "itemA", // "tre.discovery.required.2": "itemB", // "tre.discovery.required.3": "itemC", +// "quattro.discovery.required.1": "itemA", +// "quattro.discovery.required.4": "itemB", +// "quattro.discovery.required.5": "itemC", // } // // calling ExtractSubIndexLists("uno.discovery.required") returns the array: @@ -644,23 +649,45 @@ func (m *Map) ExtractSubIndexSets(root string) []*Map { // // [ "itemA", "itemB", "itemC" ] // +// also the list may contains holes, so calling ExtractSubIndexLists("quattro.discovery.required") returns: +// +// [ "itemA", "itemB", "itemC" ] +// // Numeric subindex cannot be mixed with non-numeric, in that case only the numeric sub // index sets will be returned. func (m *Map) ExtractSubIndexLists(root string) []string { - // First check the properties with numeric sub index "root.N.xxx" + isNotDigit := func(in string) bool { + for _, r := range in { + if r < '0' || r > '9' { + return true + } + } + return false + } + + // Extract numeric keys + subProps := m.SubTree(root) + indexes := []int{} + for _, key := range subProps.o { + if isNotDigit(key) { + continue + } + if idx, err := strconv.Atoi(key); err == nil { + indexes = append(indexes, idx) + } + } + sort.Ints(indexes) + res := []string{} - portIDPropsSet := m.SubTree(root) - idx := 0 haveIndexedProperties := false - for { - k := fmt.Sprintf("%d", idx) - idx++ - if v, ok := portIDPropsSet.GetOk(k); ok { + for i, idx := range indexes { + if i > 0 && idx == indexes[i-1] { + // de-duplicate cases like "05" and "5" + continue + } + if v, ok := subProps.GetOk(strconv.Itoa(idx)); ok { haveIndexedProperties = true res = append(res, v) - } else if idx > 1 { - // Always check sub-id 0 and 1 (https://github.com/arduino/arduino-cli/issues/456) - break } } diff --git a/properties_test.go b/properties_test.go index 1283c64..16a4c01 100644 --- a/properties_test.go +++ b/properties_test.go @@ -357,32 +357,24 @@ func TestExtractSubIndexLists(t *testing.T) { "quattro.discovery.required.1": "itemB", "quattro.discovery.required.2": "itemC", "cinque.discovery.something": "itemX", + "sei.discovery.something.1": "itemA", + "sei.discovery.something.2": "itemB", + "sei.discovery.something.5": "itemC", + "sei.discovery.something.12": "itemD", + "sette.discovery.something.01": "itemA", + "sette.discovery.something.2": "itemB", + "sette.discovery.something.05": "itemC", + "sette.discovery.something.5": "itemD", } m := NewFromHashmap(data) - s1 := m.ExtractSubIndexLists("uno.discovery.required") - require.Len(t, s1, 1) - require.Equal(t, s1[0], "item") - - s2 := m.ExtractSubIndexLists("due.discovery.required") - require.Len(t, s2, 3) - require.Equal(t, s2[0], "item1") - require.Equal(t, s2[1], "item2") - require.Equal(t, s2[2], "item3") - - s3 := m.ExtractSubIndexLists("tre.discovery.required") - require.Len(t, s3, 3) - require.Equal(t, s3[0], "itemA") - require.Equal(t, s3[1], "itemB") - require.Equal(t, s3[2], "itemC") - - s4 := m.ExtractSubIndexLists("quattro.discovery.required") - require.Len(t, s4, 2) - require.Equal(t, s4[0], "itemB") - require.Equal(t, s4[1], "itemC") - - s5 := m.ExtractSubIndexLists("cinque.discovery.required") - require.Len(t, s5, 0) + require.Equal(t, []string{"item"}, m.ExtractSubIndexLists("uno.discovery.required")) + require.Equal(t, []string{"item1", "item2", "item3"}, m.ExtractSubIndexLists("due.discovery.required")) + require.Equal(t, []string{"itemA", "itemB", "itemC"}, m.ExtractSubIndexLists("tre.discovery.required")) + require.Equal(t, []string{"itemB", "itemC"}, m.ExtractSubIndexLists("quattro.discovery.required")) + require.Equal(t, []string{}, m.ExtractSubIndexLists("cinque.discovery.required")) + require.Equal(t, []string{"itemA", "itemB", "itemC", "itemD"}, m.ExtractSubIndexLists("sei.discovery.something")) + require.Equal(t, []string{"itemB", "itemD"}, m.ExtractSubIndexLists("sette.discovery.something")) } func TestLoadingNonUTF8Properties(t *testing.T) {