Harneet.Lamba
Harneet.Lamba

Reputation: 301

Julia - last() does not work inside the function

I am writing the below code, and in the code the last() function does not work. I get the below error.

ERROR: UndefVarError: last not defined

But when I use last() outside of the function with same logic it works.

I am trying to write the below function -

function mergeOverlappingIntervals(intervals)
    sort!(intervals, by = x -> intervals[1])
    new_interval = intervals[1]
    for i in range(2, length(intervals))
        if last(new_intervals)[2] >= intervals[i][1]
            last(new_intervals) = [minimum!(last(new_intervals)[1], intervals[i][1]), maximum!(last(new_intervals)[2], intervals[2])]
        else
            push!(new_interval, intervals[i])
        end
    end
end

Can you please help?

Upvotes: 4

Views: 190

Answers (3)

Harneet.Lamba
Harneet.Lamba

Reputation: 301

I was able to solve the problem by taking the suggestions from all the answers posted. Thank you.

Below is the code -

function mergeOverlappingIntervals(intervals)
    sort!(intervals, by = x -> intervals[1])
    new_interval = [intervals[1]]
    for i in range(2, length(intervals))
        if new_interval[end][2] >= intervals[i][1]
            new_interval[end] = [min(new_interval[end][1], intervals[i][1]), max(new_interval[end][2], intervals[i][2])]
        else
            push!(new_interval, intervals[i])
        end
    end
    return new_interval
end

Upvotes: 0

AboAmmar
AboAmmar

Reputation: 5559

A straightforward implementation, after fixing two errors. last() cannot be assigned to as others said, and minimum or maximum are used with arrays, you want max here to compare scalars. Finally you should return the new merged stack of intervals.

function mergeIntervals(intervals)
    sort!(intervals)
    stack = [intervals[1]]
    for i in 2:length(intervals)
        if stack[end][2] < intervals[i][1]
            push!(stack, intervals[i])
        else
            stack[end][2] = max(stack[end][2], intervals[i][2])
        end
    end
    return stack
end

Test an example:

intervals = [[6, 8], [1, 9], [2, 4], [4, 7]]
mergeIntervals(intervals) 
[[1, 9]]

Upvotes: 1

Bill
Bill

Reputation: 6086

If you are trying to merge the intervals, note that your sort does not work since `by = x -> intervals[1] is a constant: you wanted to say by = x -> x[1]. and the default sort on vectors does that already.

You could instead do:

using Random

intervals = shuffle([[1, 2], [3, 5], [4, 6]])

function mergeintervals(intervals)
    @assert length(intervals) > 1
    sort!(intervals)
    a = [copy(intervals[begin])]
    for v in @view intervals[begin+1:end]
        if a[end][end] >= v[begin]
            if a[end][end] < v[end]
                a[end][end] = v[end]
            end
        else
            push!(a, copy(v))
        end
    end
    return a
end

@show mergeintervals(intervals) # [[1, 2], [3, 6]]

The reason last(x) does not work is that (unlike x[end]) it does not return an lvalue, that is, it does not produce a value or syntactic expression that you can assign to. So Julia thinks you are trying to redefine the function last(x) when you attempt to assign to it (as DNF pointed out). (An lvalue is something that can be used as the left hand side of an assignment, which in Julia does not mean it is a direct memory address: see below).

Upvotes: 2

Related Questions