6

I need to create a list containing a predefined number of zeros.

I know that I can create an empty one with let foo = [] but I would need to initialize it with a number of zeros contained in a variable.

:h List doesn't seem to mention this use case, what's the most efficient way to do that?


A second part of my question is about nested lists:

I need to create a list of lists, with the number of inner lists contained in a variable and the length of the inner lists in another variable. (The inner lists are all of the same size)

Is it possible to the method used for one list in this case? If not how to do it?

2 Answers 2

6

You can combine the map and range function for that:

:echo map(range(4), 0)
[0, 0, 0, 0]

range(4) returns a list of number defined by the arguments:

[0, 1, 2, 3]

map([0, 1, 2, 3], 0) replace every element in the array with 0

You can use the following function:

function! Fill(len, char)
    return map(range(a:len), a:char)
endfunction

You can use it like so:

:echo Fill(4, 'a')
['a', 'a', 'a', 'a']

For the recursive fill, you can use the following function:

function! FillRecursive(len1, len2, char)
  if a:len2 == -1
    return map(range(a:len1), 'a:char')
  endif

  return map(range(a:len1), 'FillRecursive(a:len2, -1, a:char)')
endfunction

You can use it like so:

:echo FillRecursive(4,4,'a')
[['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a'], ['a', 'a', 'a', 'a']]

You can see the interesting part in the map: instead of passing the l:inner directly, because the map function cannot accept a list, but it can accept the literal string containing the list.

5
repeat([0], 4)

is what you're looking for.

:h repeat()

Regarding the inner lists/matrices, we could think about:

echo repeat([repeat([0], 5)], 2)

however, it will do a shallow copy of the first inner list. See

let t = repeat([repeat([0], 5)], 2)
let t[0][0] = 42
echo t[0]
echo t[1]

All inner lists need to be copied. We are back to map()+copy(). Note that somehow with a more complex need may require the use of deepcopy() instead.

let t = map(repeat([repeat([0], 5)], 2), 'copy(v:val)')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.