Skip to content

Commit 02ecfc6

Browse files
Improve unique function: clarify sorted parameter semantics and optimize edge cases
1 parent adc27a4 commit 02ecfc6

File tree

1 file changed

+25
-30
lines changed

1 file changed

+25
-30
lines changed

src/stdlib_sorting_unique_impl.fypp

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -22,49 +22,44 @@ contains
2222
${t1}$, intent(in) :: array(:)
2323
logical(lk), intent(in), optional :: sorted
2424
${t2}$, allocatable :: unique_values(:)
25-
25+
2626
${t2}$ :: temp_array(size(array))
2727
logical :: mask(size(array))
28-
integer :: i, j, n, unique_count
29-
logical :: want_sorted
30-
31-
want_sorted = optval(sorted, .false.)
32-
28+
integer :: i, n
29+
logical :: is_input_sorted
30+
3331
n = size(array)
32+
33+
! Handle edge cases first
3434
if (n == 0) then
35+
! Return empty array for empty input
3536
allocate(unique_values(0))
3637
return
38+
else if (n == 1) then
39+
! For single-element arrays, return that element directly
40+
allocate(unique_values(1))
41+
unique_values(1) = array(1)
42+
return
3743
endif
38-
39-
! Create a temporary copy that may be sorted
40-
if (want_sorted) then
41-
temp_array = array
42-
call sort(temp_array)
43-
else
44-
temp_array = array
45-
endif
46-
44+
45+
! Determine if the input is already sorted
46+
is_input_sorted = optval(sorted, .false.)
47+
48+
! Create a temporary copy and sort it if needed
49+
temp_array = array
50+
if (.not. is_input_sorted) call sort(temp_array)
51+
4752
! Find unique elements using a mask
4853
! Start with first element always marked as unique
4954
mask(1) = .true.
50-
55+
5156
! Compare each element with previous to mark duplicates
52-
do i = 2, n
57+
do concurrent (i=2:n)
5358
mask(i) = temp_array(i) /= temp_array(i-1)
5459
end do
55-
56-
! Count unique elements and allocate result array
57-
unique_count = count(mask)
58-
allocate(unique_values(unique_count))
59-
60-
! Extract unique elements to result array
61-
j = 0
62-
do i = 1, n
63-
if (mask(i)) then
64-
j = j + 1
65-
unique_values(j) = temp_array(i)
66-
endif
67-
end do
60+
61+
! Extract unique elements to result array using pack
62+
unique_values = pack(temp_array, mask)
6863
end function ${name1}$_unique
6964

7065
#:endfor

0 commit comments

Comments
 (0)