{"action":"created","issue":{"url":"https://api.github.com/repos/pandastrike/fairmont/issues/40","labels_url":"https://api.github.com/repos/pandastrike/fairmont/issues/40/labels{/name}","comments_url":"https://api.github.com/repos/pandastrike/fairmont/issues/40/comments","events_url":"https://api.github.com/repos/pandastrike/fairmont/issues/40/events","html_url":"https://github.com/pandastrike/fairmont/issues/40","id":63591617,"number":40,"title":"where() and array_equal()","user":{"login":"PandaPup","id":6767448,"avatar_url":"https://avatars.githubusercontent.com/u/6767448?v=3","gravatar_id":"","url":"https://api.github.com/users/PandaPup","html_url":"https://github.com/PandaPup","followers_url":"https://api.github.com/users/PandaPup/followers","following_url":"https://api.github.com/users/PandaPup/following{/other_user}","gists_url":"https://api.github.com/users/PandaPup/gists{/gist_id}","starred_url":"https://api.github.com/users/PandaPup/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PandaPup/subscriptions","organizations_url":"https://api.github.com/users/PandaPup/orgs","repos_url":"https://api.github.com/users/PandaPup/repos","events_url":"https://api.github.com/users/PandaPup/events{/privacy}","received_events_url":"https://api.github.com/users/PandaPup/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":{"login":"dyoder","id":1859,"avatar_url":"https://avatars.githubusercontent.com/u/1859?v=3","gravatar_id":"","url":"https://api.github.com/users/dyoder","html_url":"https://github.com/dyoder","followers_url":"https://api.github.com/users/dyoder/followers","following_url":"https://api.github.com/users/dyoder/following{/other_user}","gists_url":"https://api.github.com/users/dyoder/gists{/gist_id}","starred_url":"https://api.github.com/users/dyoder/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dyoder/subscriptions","organizations_url":"https://api.github.com/users/dyoder/orgs","repos_url":"https://api.github.com/users/dyoder/repos","events_url":"https://api.github.com/users/dyoder/events{/privacy}","received_events_url":"https://api.github.com/users/dyoder/received_events","type":"User","site_admin":false},"milestone":null,"comments":2,"created_at":"2015-03-22T23:56:52Z","updated_at":"2015-03-25T22:06:12Z","closed_at":"2015-03-25T22:06:12Z","body":"@dyoder, there is a function in `underscore` that I think is very handy, called `where()`.  Provided an array of objects and a query object, `where()` returns an array with only those objects that contain the query object as a subset.\r\n\r\nI liked it so much that when we switched the Huxley CLI over to Fairmont, [I re-implemented it](https://github.com/pandastrike/huxley/blob/development/alpha-02/huxley-cli/src/helpers.coffee#L85-L99).  However, I went back and thought about the style I've been trying to practice.  I think the version below is much closer to something that could be included in Fairmont, so I'd like to submit it to you.  \r\n\r\nThere are a couple questions of scope, however.  It currently only works on an array of objects and accepts only one query object.\r\n- Should we generalize it to accept an array of strings, numbers, etc....\r\n- Should we generalize it to accept multiple queries for matching?\r\n\r\nI toyed with the idea of making an awesome, overloaded filter function but there are so many edge cases it was like wrangling cats, haha.  \r\n\r\n### Object Filter Draft, where()\r\n```coffee\r\n# Filters an array of objects against a single \"query\" object.  If no objects match, an empty array is returned.\r\n{async, collect, deep_equal, partial, select, _} = require \"fairmont\"\r\nwhere = async (query, array) ->\r\n  match = (a, b) ->\r\n    intersect = (a, b) -> key for key in Object.keys(b) when (deep_equal a[key], b[key])\r\n    if intersect(a, b).length == Object.keys(a).length then true else false\r\n\r\n    collect yield select (partial match, query, _), array\r\n```\r\n\r\nDuring testing, I realized that not only does the `==` operator fail to compare arrays, so does `deep_equal`.  I wrote a draft of a function that performs a comparison on arrays and recurses to ensure a deep comparison.  Since this could possibly be expensive, it tries to escape and return `false` whenever it confirms a difference.  Maybe we can work this into `deep_equal` eventually. (after removing the `deep_equal` usage, haha.)\r\n\r\n### Deep Array Comparison Draft, array_equal()\r\n``` coffee\r\n# Performs deep comparison of two arrays.  Returns true or false.\r\n{type, deep_equal} = require \"fairmont\"\r\narray_equal = (a, b) ->\r\n  throw \"\\\"array_equal\\\" accepts only arrays.\" unless type(a) == \"array\" && type(b) == \"array\"\r\n  return false unless a.length == b.length\r\n\r\n  compare = (a, b) ->\r\n    for i in [0..a.length - 1]\r\n      if (type(a[i]) == \"array\") && (type(b[i]) == \"array\")\r\n        throw false unless  (a.length == b.length) && (compare a[i], b[i])\r\n      else\r\n        throw false unless deep_equal a[i], b[i]\r\n    true\r\n\r\n  try\r\n    compare a, b\r\n  catch e\r\n    false\r\n```\r\n```coffee\r\nassert array_equal [[1, 2, 3], 2, 3], [[1, 2, 3], 2, 3]\r\nassert !array_equal [[1, 2, 30], 2, 3], [[1, 2, 3], 2, 3]\r\nassert array_equal [[[{one: {two:2, three:3}}, 2, 3], 2, 3], 2, 3], [[[{one: {two:2, three:3}}, 2, 3], 2, 3], 2, 3]\r\n```"},"comment":{"url":"https://api.github.com/repos/pandastrike/fairmont/issues/comments/86232538","html_url":"https://github.com/pandastrike/fairmont/issues/40#issuecomment-86232538","issue_url":"https://api.github.com/repos/pandastrike/fairmont/issues/40","id":86232538,"user":{"login":"dyoder","id":1859,"avatar_url":"https://avatars.githubusercontent.com/u/1859?v=3","gravatar_id":"","url":"https://api.github.com/users/dyoder","html_url":"https://github.com/dyoder","followers_url":"https://api.github.com/users/dyoder/followers","following_url":"https://api.github.com/users/dyoder/following{/other_user}","gists_url":"https://api.github.com/users/dyoder/gists{/gist_id}","starred_url":"https://api.github.com/users/dyoder/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dyoder/subscriptions","organizations_url":"https://api.github.com/users/dyoder/orgs","repos_url":"https://api.github.com/users/dyoder/repos","events_url":"https://api.github.com/users/dyoder/events{/privacy}","received_events_url":"https://api.github.com/users/dyoder/received_events","type":"User","site_admin":false},"created_at":"2015-03-25T22:06:12Z","updated_at":"2015-03-25T22:06:12Z","body":"I've added `query` and `where` support to alpha 17. Still not sure what the failing case is for `deep_equal` on arrays. But I'm closing this for now. Please open a new ticket with the failing test case for arrays."}}