3

I am trying to run a 2 for loops to access 2 elements within an array, (e.g.)

x = 100
for i in eachindex(x-1)
  for j in 2:x
    doSomething = Array[i] + Array[j]
  end
end

And often (not always) I get this error or similar:

LoadError: BoundsError: attempt to access 36-element Array{Any,1} at index [64]

I understand there are proper ways to run these loops to avoid bounds errors, hence my use of eachindex(x-1) == 1:x, how would I do this for 2:x?

I am relatively new to Julia, if this is not the reason for the bounds error, what could it be? - Thanks

EDIT: shortened version of what I am trying to run (Also yes, vector-arrays)

all_people = Vector{type_person}() # 1D Vector of type person
size = length(all_people)

... fill vector array to create an initial population of people ...

# Now add to the array using existing parent objects
for i in 1:size-1
  for j in 2:size
    if all_people[i].age >= all_people[j].age # oldest parent object forms child variable
      child = type_person(all_people[i])
    else
      child = type_person(all_people[j])
    end
    push!(all_people, child) # add to the group of people
  end
end
Adrian Azza
  • 109
  • 7
  • Can you include a minimal working example of the problem? Otherwise it’s hard to say. Also, indexing into the `Array` type is confusing and or incorrect. – StefanKarpinski Jun 14 '20 at 17:03
  • @StefanKarpinski will include an example, could you suggest an alternative method? Im relatively new to this so would be helpful? – Adrian Azza Jun 14 '20 at 17:11
  • can you show the declaration of `Array` ? This snippet works fine for me – San Jun 14 '20 at 17:21
  • Looks like `all_people` is of size 36, but you are trying to access index higher than that. – San Jun 14 '20 at 17:24
  • @San It tries to access position 64 not 37, so wouldn't work (also I did try it haha). I have read the Julia documentation (briefly) and at some point it says there is a correct way of indexing arrays - which I do not know of ;( – Adrian Azza Jun 14 '20 at 17:27
  • I would suggest you to print and see the values of `size` and `length(all_people)` just before the 2 for loops, to ensure they are same. – San Jun 14 '20 at 17:36
  • @San have done that and they are correct. I think the issue is to do with how Julia gets the array index. Thanks tho – Adrian Azza Jun 14 '20 at 17:39

1 Answers1

3

I made few guesses but perhaps this is the code you want:

struct Person
    parent::Union{Nothing,Person}
    age::Int
end
Person(parent::Person) = Person(parent,0)

N = 100
population = Person.(nothing, rand(20:50,N))
for i in 1:(N-1)
    for j in (i+1):N
        parent = population[population[i].age >= population[j].age ? i : j]
        push!(population, Person(parent))
    end
end

Notes:

  1. For this types of code also have a look at the Parameters.jl package - it is very convenient for agent constructors
  2. Notice how the constructor has been vectorized
  3. Types in Julia are named starting with capital letters (and hence Person)
  4. I assume that for children you wanted to try each pair of parents hence this is how to construct the loop. You do not need to evaluate the same pair of parents as (i,j) and then later as (j,i).
  5. eachindex should be used on Arrays - does not make sense on scalars
Przemyslaw Szufel
  • 40,002
  • 3
  • 32
  • 62
  • This didn't "Solve" it as i found out that I was stupidly creating a variable called 'i' inside the for loop which is creates the i index, so my bad. However your solution did improve my code and helpful notes - thanks from a noobe – Adrian Azza Jun 15 '20 at 12:09
  • 1
    OK. Simply treat this my example as a pattern for your code layout. – Przemyslaw Szufel Jun 15 '20 at 12:12