# Derived Array: Select Record

In my code, I have a 2D array

``````integer, allocatable :: elements(:,:)
```

```

and define some constants

``````integer, parameter :: TYP = 1
integer, parameter :: WIDTH = 2
integer, parameter :: HEIGHT = 3
! ...
integer, parameter :: NUM_ENTRIES = 10
```

```

and highlight something like

``````allocate(elements(NUM_ENTRIES,10000))
```

```

so that I can access elements like

``````write(*,*) elements(WIDTH,100) ! gives the width of the 100th element
```

```

Now I would like to have not only an integer, but a mixture of types for each element. So I define a derived type

``````type Element
logical active
integer type
real width
! etc
end type
```

```

and use an array of elements

``````type(Element), allocatable :: elements(:)
```

```

With the 2d array version, I could call a subroutine telling it which entry to use. For example.

``````subroutine find_average(entry, avg)
integer, intent(in) :: entry
real, intent(out) :: avg
integer i,
real s

s = 0
do i = lbound(elements,1), ubound(elements,1)
if (elements(TYP,i) .gt. 0) s = s + elements(entry,i)
end do
avg = s/(ubound(elements,1)-lbound(elements,1))
end subroutine
```

```

So, I could `call find_average(HEIGHT)`

find the average height, or go through `WIDTH`

to get the average width. (And my routines do more complex things than finding the average height or width, this is just an example.)

Question: How can I use different types (as with a derived type), but also use my functions to work with different records (as in the example subroutine)?

+3

source to share

For the case of an array, instead of passing array and index i in the argument, you can pass a single array of arguments (i). When you switch to the derived type, the same way you can pass variable_of_type% element, instead of transferring the entire peremennyy_i_i_i_i_i_i_i_i_i_i_i_i_i_po_i_po_i_po_i_po_ooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee If the code has to be different for different types of items (eg, logical, integer, real), then you can write specific procedures for each, but then call with a common name via a common interface block. The compiler should be able to distinguish common interface procedures with some characteristics of the arguments, here is their type.For example code where the distinguishing characteristic is an array rank, seehow to write a wrapper for 'allocate'

EDIT: sample code. does it do what you want?

``````module my_subs

implicit none

interface my_sum
module procedure sum_real, sum_int
end interface my_sum

contains

subroutine sum_real (array, tot)
real, dimension(:), intent (in) :: array
real, intent (out) :: tot
integer :: i

tot = 1.0
do i=1, size (array)
tot = tot * array (i)
end do
end subroutine sum_real

subroutine sum_int (array, tot)
integer, dimension(:), intent (in) :: array
integer, intent (out) :: tot
integer :: i

tot = 0
do i=1, size (array)
tot = tot + array (i)
end do
end subroutine sum_int

end module my_subs

program test_dt

use my_subs

implicit none

type my_type
integer weight
real length
end type my_type

type (my_type), dimension (:), allocatable :: people

allocate (people (2))

people (1) % weight = 1
people (1) % length = 1.0
people (2) % weight = 2
people (2) % length = 2.0

call my_sum ( people (:) % weight, answer % weight )
write (*, *)  answer % weight

call my_sum ( people (:) % length, answer % length )
write (*, *)  answer % length

end program test_dt
```

```
+4

source

All Articles