Last Friday of each month: Difference between revisions

Content added Content deleted
(→‎Functional (ES 5): Amended comment)
(→‎{{header|AppleScript}}: Partial translation of the JavaScript (Functional ES5) version)
Line 68: Line 68:
<pre>>./last_weekday_in_month friday 2012
<pre>>./last_weekday_in_month friday 2012
2012-01-27
2012-01-27
2012-02-24
2012-03-30
2012-04-27
2012-05-25
2012-06-29
2012-07-27
2012-08-31
2012-09-28
2012-10-26
2012-11-30
2012-12-28</pre>


==AppleScript==

{{Trans|JavaScript}}


<lang JavaScript>on run
intercalate(linefeed, ¬
map(ISODate, ¬
lastWeekDaysOfYear(2012, Friday as integer)))
end run


-- lastWeekDaysOfYear :: Int -> Int -> [Date]
on lastWeekDaysOfYear(intYear, iWeekDay)
map(mClosure(my lastWeekDay, ¬
{intYear:intYear, iWeekDay:iWeekDay}), my lastDaysOfMonths(intYear))
end lastWeekDaysOfYear


-- lastWeekDay :: iLastDay, iMonth
on lastWeekDay(iLastDay, iMonth)
set iYear to intYear of my closure
calendarDate(iYear, iMonth, iLastDay - ¬
(((weekday of calendarDate(iYear, iMonth, iLastDay)) as integer) + ¬
(7 - (iWeekDay of my closure))) mod 7)
end lastWeekDay


-- lastDaysOfMonths :: Int -> [Int]
on lastDaysOfMonths(y)
if (0 = y mod 4) and (0 ≠ y mod 100) or (0 = y mod 400) then
set iFeb to 29
else
set iFeb to 28
end if
{31, iFeb, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
end lastDaysOfMonths



-- GENERIC FUNCTIONS

-- calendarDate :: Int -> Int -> Int -> Date
on calendarDate(intYear, intMonth, intDay)
tell (current date)
set {its year, its month, its day, its time} to {intYear, intMonth, intDay, 0}
return it
end tell
end calendarDate

-- ISODate :: Date -> String
on ISODate(dte)
(((year of dte) as string) & ¬
"-" & text items -2 thru -1 of ¬
("0" & ((month of dte) as integer) as string)) & ¬
"-" & text items -2 thru -1 of ¬
("0" & day of dte)
end ISODate

-- intercalate :: Text -> [Text] -> Text
on intercalate(strText, lstText)
set {dlm, my text item delimiters} to {my text item delimiters, strText}
set strJoined to lstText as text
set my text item delimiters to dlm
return strJoined
end intercalate


-- Higher-order functions

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
set mf to mReturn(f)
set lng to length of xs
set lst to {}
repeat with i from 1 to lng
set end of lst to mf's lambda(item i of xs, i, xs)
end repeat
return lst
end map

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then return f
script
property lambda : f
end script
end mReturn

-- Handler -> Record -> Script
on mClosure(f, recBindings)
script
property closure : recBindings
property lambda : f
end script
end mClosure</lang>


{{Out}}

<pre>2012-01-27
2012-02-24
2012-02-24
2012-03-30
2012-03-30