nominalize
nominalize

Reputation: 345

Julia: Call previous value within Map function

I have been acclimating myself with the higher order functions like map, filter, and reduce. Honestly, I feel like I'm cheating because the code is so clean! Anyway...

Say I am preforming a map function on an array and the output of anonymous function is dependent on the preceding value. How would i call the previous value?

For instance:

A statement to check if each value has a factor of 3

julia> A
4-element Array{Int64,1}:
  3
  6
  9
 36

julia> reduce(&, map(x-> x%3 == 0, A))
true

How would I call the previous value to check if it is a factor of the current value?

julia> reduce(&, map( x -> x==A[1] ? true : x % 3 == 0, A))
true

#I want to change the 3 to the previous value like..
psuedo code> reduce(&, map( x -> x==A[1] ? true : x % x[i-1] == 0, A))

Any ideas? Or, am I pushing the limits on this?

Upvotes: 1

Views: 456

Answers (2)

Cameron Bieganek
Cameron Bieganek

Reputation: 7674

The map function can take a multivariate function and apply it to multiple arrays. So you can apply your function to properly shifted versions of your array:

julia> A = [3, 6, 9, 36];

julia> map((x, y) -> x % y == 0, A[2:end], A[1:end-1])
3-element Array{Bool,1}:
  true
 false
  true

The ShiftedArrays.jl package provides lead and lag functions to make shifting arrays more convenient:

julia> using ShiftedArrays

julia> lag(A)
4-element ShiftedArray{Int64,Missing,1,Array{Int64,1}}:
  missing
 3       
 6       
 9

julia> map((x, x_lag) -> x % x_lag == 0, A, lag(A))
4-element Array{Union{Missing, Bool},1}:
      missing
  true       
 false       
  true

Note that lag introduces a missing value at the beginning of the shifted array. If you want to ensure that your function returns true for the first element of the array, you could modify it like this:

julia> map((x, y) -> ismissing(y) ? true : x % y == 0, A, lag(A))
4-element Array{Bool,1}:
  true
  true
 false
  true

Upvotes: 2

Bill
Bill

Reputation: 6086

Just as in a for loop, you can take elements as x in A or get elements via an index, as i in 1:length(A):

reduce(&, map(i -> A[i]==A[1] ? true : A[i] % A[i-1] == 0, 1:length(A)))

or, because it may shortcut evaluation when false:

all(i -> A[i]==A[1] ? true : A[i] % A[i-1] == 0, 1:length(A))

Upvotes: 1

Related Questions