{"id":706,"date":"2010-12-02T13:00:31","date_gmt":"2010-12-02T01:00:31","guid":{"rendered":"https:\/\/www.deltics.co.nz\/blog\/?p=706"},"modified":"2010-12-02T13:02:23","modified_gmt":"2010-12-02T01:02:23","slug":"making-a-case-for-strings-the-sane-way","status":"publish","type":"post","link":"https:\/\/www.deltics.co.nz\/blog\/posts\/706\/","title":{"rendered":"Making a case for Strings, the sane way"},"content":{"rendered":"<span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">&lt; 1<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span><p><a href=\"http:\/\/delphi.fosdal.com\/\">Lars Fosdal<\/a> responded to <a href=\"https:\/\/www.deltics.co.nz\/blog\/?p=700\">my previous post<\/a> suggesting a way of implementing string support in a case-like construct (but not actually a case statement) <a href=\"http:\/\/delphi.fosdal.com\/2010\/12\/generic-case-for-strings.html\">using generics and anonymous methods<\/a>.<\/p>\n<p>All very clever, but way, way too complicated and &#8211; if you don&#8217;t mind me saying so &#8211; as ugly as sin into the bargain (imho &#8211; ymmv).<\/p>\n<p>For simple cases [sic], it is actually relatively straightforward to uses strings in a case statement.<br \/>\n<!--more--><\/p>\n<p>Just add this function to a convenient unit:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n\r\n  interface\r\n\r\n    function StringIndex(const aString: String;\r\n                         const aCases: array of String;\r\n                         const aCaseSensitive: Boolean = TRUE): Integer;\r\n\r\n  implementation \r\n\r\n    function StringIndex(const aString: String;\r\n                         const aCases: array of String;\r\n                         const aCaseSensitive: Boolean): Integer;\r\n    begin\r\n      if aCaseSensitive then\r\n      begin\r\n        for result := 0 to Pred(Length(aCases)) do\r\n          if ANSISameText(aString, aCases[result]) then\r\n            EXIT;\r\n      end\r\n      else\r\n      begin\r\n        for result := 0 to Pred(Length(aCases)) do\r\n          if ANSISameStr(aString, aCases[result]) then\r\n            EXIT;\r\n      end;\r\n\r\n      result := -1;\r\n    end;\r\n<\/pre>\n<p>And now you can use this in an ordinary case statement:<\/p>\n<pre class=\"brush: delphi; title: ; notranslate\" title=\"\">\r\n  case StringIndex(SomeString, [SelectorA,\r\n                                SelectorB,\r\n                                SelectorC]) of\r\n    0: \/\/ for SelectorA\r\n    1: \/\/ for SelectorB\r\n    2: \/\/ for SelectorC\r\n  else\r\n    \/\/ Some other SomeString\r\n  end;\r\n<\/pre>\n<p>I added a case-sensitivity switch, but more sophisticated options could be provided such as partial matching.  Similarly, there could possibly be some optimisation of the string matching within the function (perhaps triggered by a number of cases above a certain threshold), but this is the bare bones of what you need.<\/p>\n<p>In fact, I am pretty sure I&#8217;ve seen something similar to this in the past, but I can&#8217;t put my finger on when or where.<\/p>\n<p>In any event, build on, improve, embellish to your hearts content, and all with perfectly clear, concise, Pascal-like syntax in <strong>all<\/strong> versions of Delphi.<\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">[Estimated Reading Time: <\/span> <span class=\"rt-time\">&lt; 1<\/span> <span class=\"rt-label rt-postfix\">minutes]<\/span><\/span> Lars Fosdal responded to my previous post suggesting a way of implementing string support in a case-like construct (but not actually a case statement) using generics and anonymous methods. All very clever, but way, way too complicated and &#8211; if you don&#8217;t mind me saying so &#8211; as ugly as sin into the bargain (imho [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[4],"tags":[125,13,127,128],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1TKYv-bo","jetpack_sharing_enabled":true,"jetpack-related-posts":[{"id":2584,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2584\/","url_meta":{"origin":706,"position":0},"title":"Anatomy of a utility function:  BoolToStr()","date":"16 Mar 2017","format":false,"excerpt":"Jaap Van Goor was asking on FaceBook about some seemingly strange behaviour when obtaining string representations of Booleans using the Delphi RTL, which led me to revisit some familiar (and some not so familiar) old Delphi ground and take a look at the area involved in further detail. First of\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":644,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/644\/","url_meta":{"origin":706,"position":1},"title":"When is an interfaced object not an interfaced object?","date":"29 Jul 2010","format":false,"excerpt":"Answer: When it is merely the container for an interface. After a long series of observation and opinion pieces, I thought it about time I posted something a little more technical, so here we go. I think it is a well known practice to store references to objects in the\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1925,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/1925\/","url_meta":{"origin":706,"position":2},"title":"VCL Threading &#8211; Synchronization","date":"16 Oct 2013","format":false,"excerpt":"Although I am using Oxygene a lot these days, Delphi remains my tool of choice for Win32 (and x64) development, together with the VCL. Hence this post. A long time ago, in a galaxy far far away, Delphi was a Windows only development tool. 16 was the number of the\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":102,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/102\/","url_meta":{"origin":706,"position":3},"title":"Multicast Events &#8211; Part 2","date":"07 Aug 2008","format":false,"excerpt":"Having covered some of the basic use of multicast events, in this second post I shall start to build the implementation.\u00a0 In this first iteration we will provide the basics of a multicast event - managing and calling multiple handlers and the ability to enable and disable an event. The\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2164,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2164\/","url_meta":{"origin":706,"position":4},"title":"Smoketest &#8211; Some Differences With DUnit","date":"19 Nov 2013","format":false,"excerpt":"Writing tests in Smoketest is intended to enable a test developer to write tests in a way that describe themselves, without requiring the test developer to add this \"narrative\" themselves. To see this in action, I thought I would compare some simple DUnit tests with the equivalent using the Smoketest\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":2006,"url":"https:\/\/www.deltics.co.nz\/blog\/posts\/2006\/","url_meta":{"origin":706,"position":5},"title":"Blowing Smoke&#8230;","date":"01 Nov 2013","format":false,"excerpt":"To alleviate the grind of polishing and sanitising my code (and, let's be honest, just plain 'fixing' it in some cases) ready for release, I have re-kindled my participation on Stack Overflow. In a happy confluence yesterday a question came up which allowed me to exercise one of the libraries\u2026","rel":"","context":"In &quot;Delphi&quot;","img":{"alt_text":"Ready to Run","src":"https:\/\/i0.wp.com\/www.deltics.co.nz\/blog\/wp-content\/uploads\/Screen-Shot-2013-11-01-at-09.00.33.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/706"}],"collection":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/comments?post=706"}],"version-history":[{"count":4,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/706\/revisions"}],"predecessor-version":[{"id":710,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/posts\/706\/revisions\/710"}],"wp:attachment":[{"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/media?parent=706"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/categories?post=706"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.deltics.co.nz\/blog\/wp-json\/wp\/v2\/tags?post=706"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}