2

Consider this function:

function add_one(in_ar,   each) {
  for (each in in_ar) {
    in_ar[each]++
  }
}

I would like to modify it such that if a second array is provided, it would be used instead of modifying the input array. I tried this:

function add_one(in_ar, out_ar,   each) {
  if (out_ar) {
    for (each in in_ar) {
      out_ar[each] = in_ar[each] + 1
    }
  }
  else {
    for (each in in_ar) {
      in_ar[each]++
    }
  }
}
BEGIN {
  split("1 2 3 4 5", q)
  add_one(q, z)
  print z[3]
}

but I get this result:

fatal: attempt to use scalar `z' as an array
Zombo
  • 1
  • 5
  • 43
  • 62

1 Answers1

1

There are 2 problems in your script

  • the variable z isn't initialized
  • the test if(out_ar) in your second code snippet is not suited for arrays

To solve the first problem, you need to assign an array element (like z[1]=1) since there is no array declaration in awk. (You can't use similar statement like declare -A as you would do in bash).

The second problem can be solved, provided you're using GNU awk, with the function isarray() or typeof().

So your code should look like this:

function add_one(in_ar, out_ar,   each) {
  if (isarray(out_ar)) {
    for (each in in_ar) {
      out_ar[each] = in_ar[each] + 1
    }
  }
  else {
    for (each in in_ar) {
      in_ar[each]++
    }
  }
}
BEGIN {
  split("1 2 3 4 5", q)
  z[1]=1
  add_one(q, z)
  print z[3]
}

I recommend looking at this page and this page.

oliv
  • 2,586
  • 9
  • 14
  • 2
    Another way to make `z` an array is to delete it: `delete z` or `delete z[""]`, etc. Also see: https://unix.stackexchange.com/q/359592/70524 (by OP) – muru Jun 26 '18 at 06:56