{"id":291,"date":"2014-06-28T07:01:27","date_gmt":"2014-06-28T13:01:27","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=291"},"modified":"2014-06-28T07:01:27","modified_gmt":"2014-06-28T13:01:27","slug":"an-adventure-in-arrays-with-apple-swift","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/an-adventure-in-arrays-with-apple-swift\/","title":{"rendered":"An Adventure in Arrays with Apple Swift"},"content":{"rendered":"<p>No, this is not another blog post restating the obvious or reiterating what you could have read in Apple&#8217;s Swift <a href=\"https:\/\/developer.apple.com\/library\/prerelease\/ios\/documentation\/Swift\/Conceptual\/Swift_Programming_Language\/AboutTheLanguageReference.html\">language reference<\/a>.  Our goal here is to show you how to regain the lost mojo of the <code>lastObject<\/code> method of <code>NSArray<\/code>.<\/p>\n<p>For the most part arrays in Swift are mundane and appear syntactically similar to array instantiation and usage in many other languages.  A bit of Python:<\/p>\n<p>[python]<br \/>\nshoppingList = [&#8216;bananas&#8217;, &#8216;milk&#8217;, &#8216;vanilla ice cream&#8217;]<br \/>\nitemCount    = len(shoppingList)<br \/>\nprint &quot;There are %d items.&quot; % itemCount<br \/>\nfor item in shoppingList:<br \/>\n  print &quot;I need to buy %s.&quot; % item<br \/>\nprint &quot;The most important item on my list is definitely %s.&quot; % shoppingList[-1]<br \/>\n[\/python]<\/p>\n<p>How about some Ruby:<\/p>\n<p>[ruby]<br \/>\nshoppingList = [&#8216;bananas&#8217;, &#8216;milk&#8217;, &#8216;vanilla ice cream&#8217;]<br \/>\nitemCount    = shoppingList.count<br \/>\nputs &quot;There are #{itemCount} items.&quot;<br \/>\nshoppingList.each do |item|<br \/>\n  puts &quot;I need to buy #{item}&quot;<br \/>\nend<br \/>\nputs &quot;The most important item on my list is definitely #{shoppingList[-1]}.&quot;<br \/>\n[\/ruby]<\/p>\n<p>In Objective-C we would use an <code>NSArray<\/code> of <code>NSString<\/code> objects, and the most important item on our list could be retrieved with <code>lastObject<\/code>:<\/p>\n<p>[objc]<br \/>\nNSArray* shoppingList = @[@&quot;bananas&quot;, @&quot;milk&quot;, @&quot;vanilla ice cream&quot;];<br \/>\nNSLog(@&quot;The most important thing on my list is definitely %@.&quot;, [shoppingList lastObject]);<br \/>\n[\/objc]<\/p>\n<p>Let&#8217;s try that in Swift with:<\/p>\n<p>[objc]<br \/>\nvar shoppingList = [&quot;bananas&quot;, &quot;milk&quot;, &quot;vanilla ice cream&quot;]<br \/>\nvar itemCount    = shoppingList.count<br \/>\nprintln(&quot;There are \\(itemCount) items.&quot;)<br \/>\nfor item in shoppingList {<br \/>\n  println(&quot;I need to buy \\(item).&quot;)<br \/>\n}<br \/>\nprintln(&quot;The most important item on my list is definitely \\(shoppingList.lastObject)&quot;)<br \/>\n[\/objc]<\/p>\n<p>Before we get to the fact that <code>lastObject<\/code> doesn&#8217;t work, notice again how <i>scripty<\/i> Swift feels.  We suppose there are only so many syntactical constructs for <a href=\"http:\/\/www.erlang.org\/doc\/man\/array.html\">creating arrays <\/a>.  We&#8217;re glad Swift doesn&#8217;t borrow <i>too much<\/i> from Erlang.<\/p>\n<p>But we digress.  We assume Swift, like Objective-C, will give us a <code>lastObject<\/code> property or method on our array.  Oh, no, it doesn&#8217;t.  <code>Playground execution failed: error: <REPL>:18:61: error: 'Array<String>' does not have a member named 'lastObject'<br \/>\nprintln(\"The most important item on my list is definitely \\(shoppingList.lastObject)\")<\/code>.  Let&#8217;s try the <code>array[-1]<\/code> notation that&#8217;s popular in Python and Ruby (and I&#8217;m sure others) for obtaining the last item in an array:<\/p>\n<p>[objc]<br \/>\nprintln(&quot;The most important item on my list is definitely \\(shoppingList[-1])&quot;)<br \/>\n[\/objc]<\/p>\n<p>The horror!  <code>fatal error: Negative Array index is out of range<br \/>\nPlayground execution failed: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).<\/code>  Of course we <i>know<\/i> that Swift arrays are index-based, and that the first index is 0, and the last index of the array is <code>count - 1<\/code>.  So perhaps we can do that:<\/p>\n<p>[objc]<br \/>\nprintln(&quot;The most important item on my list is definitely \\(shoppingList[shoppingList.count-1]).&quot;)<br \/>\n[\/objc]<\/p>\n<p>We <i>can<\/i> do that, but how awful looking.  Yuck, yuck, yuck.  If it <i>feels<\/i> wrong chances are good that it is, and that just doesn&#8217;t look right.  Oddly enough, Apple does provide a <code>removeLast<\/code> method on the array, but it does indeed <i>remove<\/i> the last element (sort of like a stack <code>pop<\/code> function):<\/p>\n<p>[objc]<br \/>\nvar lastItem = shoppingList.removeLast()<br \/>\nprintln(&quot;The most important item on my list is definitely \\(lastItem), and now there are \\(shoppingList.count) items left.&quot;)<br \/>\n[\/objc]<\/p>\n<p>results in &#8220;The most important item on my list is definitely vanilla ice cream, and now there are 2 items left.&#8221;<\/p>\n<p>So, what if we truly do want to <i>access<\/i> but not <i>remove<\/i> the last item on the list?  Here&#8217;s a nice gem we found on <a href=\"http:\/\/stackoverflow.com\/questions\/24029474\/how-do-i-fetch-the-last-element-of-an-array-in-swift\">StackOverflow<\/a> that provides this functionality by <b>extending<\/b> the <code>Array<\/code> type.  Extensions are the Swift equivalent of Objective-C <i>categories<\/i> that are useful for &#8220;adding on&#8221; new functionality to an existing class.  Here&#8217;s the codez (we took a the <code>self.endIndex<\/code> and replaced with simply <code>endIndex<\/code> at the suggestion of another reader):<\/p>\n<p>[objc]<br \/>\nextension Array {<br \/>\n    var lastObject: T {<br \/>\n        return self[endIndex &#8211; 1]<br \/>\n    }<br \/>\n}<br \/>\n[\/objc]<\/p>\n<p>Let&#8217;s try it in the playground:<\/p>\n<p>[objc]<br \/>\nprintln(&quot;The most important item on my list is definitely \\(shoppingList.lastObject).&quot;)<br \/>\n[\/objc]<\/p>\n<p>now results in what we expect, and that&#8217;s the most important item on my list is definitely vanilla ice cream.  What can we say, we love banana milk shakes.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>No, this is not another blog post restating the obvious or reiterating what you could have read in Apple&#8217;s Swift language reference. Our goal here is to show you how to regain the lost mojo of the lastObject method of NSArray. For the most part arrays in Swift are mundane and appear syntactically similar to [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-291","post","type-post","status-publish","format-standard","hentry","category-swift"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/291"}],"collection":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/comments?post=291"}],"version-history":[{"count":6,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/291\/revisions"}],"predecessor-version":[{"id":297,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/291\/revisions\/297"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=291"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=291"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=291"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}