{"id":4320,"date":"2016-06-08T02:48:14","date_gmt":"2016-06-08T02:48:14","guid":{"rendered":"http:\/\/www.garysieling.com\/blog\/?p=4320"},"modified":"2016-06-08T02:48:14","modified_gmt":"2016-06-08T02:48:14","slug":"scala-filter-vs-withfilter","status":"publish","type":"post","link":"https:\/\/www.garysieling.com\/blog\/scala-filter-vs-withfilter\/","title":{"rendered":"Scala: filter vs withFilter"},"content":{"rendered":"<p>Scala provides two variations on &#8220;filter&#8221; which at first glance appear similar:<\/p>\n<pre lang=\"scala\">\nList(\"a\", \"b\", \"c\").filter(_ == \"b\")\nres3: List[String] = List(b)\n<\/pre>\n<p>Comparatively, &#8220;withFilter&#8221; takes the same syntax, but returns an object:<\/p>\n<pre lang=\"scala\">\nList(\"a\", \"b\", \"c\").withFilter(_ == \"b\")\nres4: scala.collection.generic.FilterMonadic[String,List[String]] = \nscala.collection.TraversableLike$WithFilter@32ae8f27\n<\/pre>\n<p>The difference between these two is that &#8220;withFilter&#8221; doesn&#8217;t do any work, until values are pulled from the collection. In this sense, it is exactly like a view, although it is a single function implementation vs. all the other features views would add.<\/p>\n<p>Once you&#8217;ve applied &#8220;withFilter, you&#8217;re pretty committed &#8211; the resulting thing doesn&#8217;t let you switch back to filter, punishing you with an ugly error:<\/p>\n<pre lang=\"scala\">\nscala> List(\"a\", \"b\", \"c\").withFilter(_ == \"b\").filter(x => true)\n<console>:12: error: value filter is not a member of \nscala.collection.generic.FilterMonadic[String,List[String]]\n\n       List(\"a\", \"b\", \"c\").withFilter(_ == \"b\").filter(x => true)\n<\/pre>\n<p>On the other hand, you can apply withFilter again:<\/p>\n<pre lang=\"scala\">\nList(\"a\", \"b\", \"c\")\n  .withFilter(_ == \"b\")\n  .withFilter(x => true)\n\nres7: scala.collection.generic.FilterMonadic[String,List[String]] = \nscala.collection.TraversableLike$WithFilter@144e36ae\n<\/pre>\n<p>To realize the resulting collection, you need to do whatever your final operation is (e.g. map), to get the results back:<\/p>\n<pre lang=\"scala\">\nList(\"a\", \"b\", \"c\")\n  .withFilter(_ == \"b\")\n  .map(x => x)\n\nres9: List[String] = List(b)\n<\/pre>\n<p>And there, you have the expected result.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Understanding the difference between two scala filtering options; filter and withFilter<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[4],"tags":[480],"aioseo_notices":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/4320"}],"collection":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/comments?post=4320"}],"version-history":[{"count":0,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/4320\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/media?parent=4320"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/categories?post=4320"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/tags?post=4320"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}