У меня есть такой массив ...

a["a"]                = "aa"
a["b"]                = "ab"
a["c"]                = "ac"
a["d"]["a"]           = "ada"
a["d"]["b"]["a"]      = "adba"
a["e"]["a"]["a"]["a"] = "aeaaa"

... и хочу его клонировать

clone(b, a)

Вот что я пробовал до сих пор:

function clone(lhs, rhs){

    for (i in rhs) {
        if (typeof(arr[i]) == "array"){
            clone(lhs[i], rhs[i])
        } else {
            lhs[i] = rhs[i]
        }
    }
}

Но это явно не работает, потому что b["d"] не создается до того, как a["d"]["a"] присваивается b["d"]["a"]. Вторая проблема заключается в том, что b["d"] следует набирать как array.

4
Firmin Martin 14 Июл 2018 в 19:19

1 ответ

Лучший ответ

Вам необходимо инициализировать подмассив перед клонированием в него:

function clone(lhs, rhs) {
    for (i in rhs) {
        if (isarray(rhs[i])) {
            lhs[i][1] = ""
            delete lhs[i][1]
            clone(lhs[i], rhs[i])
        } else {
            lhs[i] = rhs[i]
        }
    }
}

Трюк с записью значения, а затем удалением упоминается на справочной странице gawk.

(Я также исправил обнаружение массива, используя isarray.)

5
Stephen Kitt 14 Июл 2018 в 19:07
См. также copy_array() в stackoverflow.com/q/62179750/1745001, который я основал на walk_array() из руководства gawk, но функционально почти идентична вышеприведенной функции clone() (с перевернутыми аргументами), за исключением того, что copy_array() удалит целевой массив (lhs выше) перед его заполнением и, таким образом, гарантирует что цель заканчивается копией оригинала, а не надмножеством исходного массива плюс все, что ранее хранилось в целевом массиве.
 – 
Ed Morton
24 Авг 2020 в 17:44