Repository: spf13/viper (go)

Issue:
Accessing array slices fails for non-lowercase keys
### Preflight Checklist

- [X] I have searched the [issue tracker](https://www.github.com/spf13/viper/issues) for an issue that matches the one I want to file, without success.
- [X] I am not looking for support or already pursued the available [support channels](https://github.com/spf13/viper/issues/new/choose) without success.
- [X] I have checked the [troubleshooting guide](https://github.com/spf13/viper/blob/master/TROUBLESHOOTING.md) for my problem, without success.

### Viper Version

master

### Go Version

1.17.9

### Config Source

Files

### Format

YAML

### Repl.it link

_No response_

### Code reproducing the issue

```go
diff --git a/viper_test.go b/viper_test.go
index c41a1e7..536a53d 100644
--- a/viper_test.go
+++ b/viper_test.go
@@ -2517,6 +2517,7 @@ func TestKeyDelimiter(t *testing.T) {
 
 var yamlDeepNestedSlices = []byte(`TV:
 - title: "The expanse"
+  originalNetwork: "syfy"
   seasons:
   - first_released: "December 14, 2015"
     episodes:
@@ -2547,6 +2548,7 @@ func TestSliceIndexAccess(t *testing.T) {
        require.NoError(t, err)
 
        assert.Equal(t, "The expanse", v.GetString("tv.0.title"))
+       assert.Equal(t, "syfy", v.GetString("tv.0.originalNetwork"))
        assert.Equal(t, "February 1, 2017", v.GetString("tv.0.seasons.1.first_released"))
        assert.Equal(t, "Static", v.GetString("tv.0.seasons.1.episodes.2.title"))
        assert.Equal(t, "December 15, 2015", v.GetString("tv.0.seasons.0.episodes.1.air_date"))
```


### Expected Behavior

If my config contains an array, and one of the sub-keys in that array is non-lowercase (ie contains one or more capital letters), Viper is unable to retrieve the key using slice notation.

I modified a simple unit test to contain this array element:
```
- title: "The expanse"
  originalNetwork: "syfy"
  ```

When accessing the value with `v.GetString("tv.0.originalNetwork")`, I expect to receive the value "syfy".

### Actual Behavior

An empty string is returned.

### Steps To Reproduce

_No response_

### Additional Information

_No response_

Pull request:
Recurse into arrays when converting keys to lowercase
Fixes #1386

Patch:
diff --git a/util.go b/util.go
index ee7a86d..64e6575 100644
--- a/util.go
+++ b/util.go
@@ -64,18 +64,25 @@ func copyAndInsensitiviseMap(m map[string]interface{}) map[string]interface{} {
 	return nm
 }
 
+func insensitiviseVal(val interface{}) interface{} {
+	switch val.(type) {
+	case map[interface{}]interface{}:
+		// nested map: cast and recursively insensitivise
+		val = cast.ToStringMap(val)
+		insensitiviseMap(val.(map[string]interface{}))
+	case map[string]interface{}:
+		// nested map: recursively insensitivise
+		insensitiviseMap(val.(map[string]interface{}))
+	case []interface{}:
+		// nested array: recursively insensitivise
+		insensitiveArray(val.([]interface{}))
+	}
+	return val
+}
+
 func insensitiviseMap(m map[string]interface{}) {
 	for key, val := range m {
-		switch val.(type) {
-		case map[interface{}]interface{}:
-			// nested map: cast and recursively insensitivise
-			val = cast.ToStringMap(val)
-			insensitiviseMap(val.(map[string]interface{}))
-		case map[string]interface{}:
-			// nested map: recursively insensitivise
-			insensitiviseMap(val.(map[string]interface{}))
-		}
-
+		val = insensitiviseVal(val)
 		lower := strings.ToLower(key)
 		if key != lower {
 			// remove old key (not lower-cased)
@@ -86,6 +93,12 @@ func insensitiviseMap(m map[string]interface{}) {
 	}
 }
 
+func insensitiveArray(a []interface{}) {
+	for i, val := range a {
+		a[i] = insensitiviseVal(val)
+	}
+}
+
 func absPathify(logger Logger, inPath string) string {
 	logger.Info("trying to resolve absolute path", "path", inPath)
 


Test patch:
diff --git a/viper_test.go b/viper_test.go
index c41a1e7..2a3dabc 100644
--- a/viper_test.go
+++ b/viper_test.go
@@ -2516,7 +2516,10 @@ func TestKeyDelimiter(t *testing.T) {
 }
 
 var yamlDeepNestedSlices = []byte(`TV:
-- title: "The expanse"
+- title: "The Expanse"
+  title_i18n:
+    USA: "The Expanse"
+    Japan: "エクスパンス -巨獣めざめる-"
   seasons:
   - first_released: "December 14, 2015"
     episodes:
@@ -2546,11 +2549,15 @@ func TestSliceIndexAccess(t *testing.T) {
 	err := v.unmarshalReader(r, v.config)
 	require.NoError(t, err)
 
-	assert.Equal(t, "The expanse", v.GetString("tv.0.title"))
+	assert.Equal(t, "The Expanse", v.GetString("tv.0.title"))
 	assert.Equal(t, "February 1, 2017", v.GetString("tv.0.seasons.1.first_released"))
 	assert.Equal(t, "Static", v.GetString("tv.0.seasons.1.episodes.2.title"))
 	assert.Equal(t, "December 15, 2015", v.GetString("tv.0.seasons.0.episodes.1.air_date"))
 
+	// Test nested keys with capital letters
+	assert.Equal(t, "The Expanse", v.GetString("tv.0.title_i18n.USA"))
+	assert.Equal(t, "エクスパンス -巨獣めざめる-", v.GetString("tv.0.title_i18n.Japan"))
+
 	// Test for index out of bounds
 	assert.Equal(t, "", v.GetString("tv.0.seasons.2.first_released"))