{"id":15494190,"url":"https://github.com/farolfo/jcomprehension","last_synced_at":"2025-04-22T20:23:40.761Z","repository":{"id":68532490,"uuid":"63821944","full_name":"farolfo/jComprehension","owner":"farolfo","description":"Build lists in mathematical set-builder notation with Java, like { x * 2 | x E {1,2,3,4} ^ x is even }","archived":false,"fork":false,"pushed_at":"2018-01-12T21:46:20.000Z","size":42,"stargazers_count":17,"open_issues_count":0,"forks_count":4,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-03-29T18:36:29.301Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/farolfo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-20T23:40:40.000Z","updated_at":"2021-02-10T10:59:30.000Z","dependencies_parsed_at":"2023-05-07T07:24:55.090Z","dependency_job_id":null,"html_url":"https://github.com/farolfo/jComprehension","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farolfo%2FjComprehension","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farolfo%2FjComprehension/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farolfo%2FjComprehension/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/farolfo%2FjComprehension/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/farolfo","download_url":"https://codeload.github.com/farolfo/jComprehension/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250316696,"owners_count":21410591,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-02T08:12:13.849Z","updated_at":"2025-04-22T20:23:40.756Z","avatar_url":"https://github.com/farolfo.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"![jComprehension](/logo.png)\n\nBuild lists in mathematical set-builder notation with Java, like { x * 2 | x E {1,2,3,4} ^ x is even }.\n\n### Introduction\n\nWe may solve our problems using `for`+`if` statements in an imperative way, or by the usage of `map`+`filter` if we want to use a functional approach, but we have another powerful way of solving these same problems: list comprehensions. List comprehensions are syntatic constructions that are used to build lists in many languages, such as Haskell, Python or Ruby, using the algebraic set-builder notation. This notation hasn't yet been added to the Java world, and is the intention of this library to do that.\n\nFor example, let's suppose we want to get all the even numbers of a given list. In the algebra world we would so with the set-builder notation like\n```\n{ x | x E R ^ x is-even }\n```\nIn Java we may do\n```java\nList\u003cInteger\u003e evens = new ArrayList\u003c\u003e();\nfor (int n : list) {\n  if (n % 2 == 0) {\n    evens.add(n);\n  }\n}\n```\nor\n```java\nPredicate\u003cInteger\u003e isEven = x -\u003e x % 2 == 0;\nList\u003cInteger\u003e evens = list.stream().filter(isEven).collect(Collectors.toList());\n```\nThese two approaches solve our problem, but now we can also do this with the List Comprehensions approach of jComprehension\n```java\nList\u003cInteger\u003e evens = new ListComprehension\u003cInteger\u003e()\n  .suchThat(x -\u003e {\n    x.belongsTo(list);\n    x.holds(isEven);\n});\n```\n\n### API\n\nIn order to build a List as a List Comprehension you must instantiate a new `ListComprehension` object and call the `suchThat` method with the predicates you want the list to hold.\n\nThe `ListComprehension` object exposes the following methods:\n\n* `List\u003cT\u003e suchThat(Consumer\u003cVar\u003e predicates)`: Builds the list of elements with the given predicates. See below to check the methods the `Var` object exposes.\n* `List\u003cPair\u003cT, T\u003e\u003e suchThat(BiConsumer\u003cVar, Var\u003e predicates)`: Builds the list of pairs of elements with the given predicates. See below to check the methods the `Var` object exposes.\n* `ListComprehension\u003cT\u003e outputExpression(Function\u003cT, T\u003e resultTransformer)`: Sets an output expressions that will be applied to each element of the resultant list after validating the predicates.\n* `ListComprehension\u003cT\u003e outputExpression(BiFunction\u003cT, T, ?\u003e resultTransformer)`: Sets an output expressios that will be applied to each pair of elements of the resultant list after validating the predicates.\n\nWhen defining the predicates, we have to use a `Var` object in a lambda (`Predicate` or `BiPredicate`).\nThe `Var` object exposes the following methods:\n\n* `Var belongsTo(List\u003cT\u003e c)`: Defines the list where the elements belong to.\n* `Var holds(Predicate\u003cT\u003e p)`: Defines a predicate that each element of the resultant list should hold.\n* `Var is(Predicate\u003cT\u003e p)`: Alias of the `Var holds(Predicate\u003cT\u003e p)` method.\n* `Var holds(BiPredicate\u003cT, T\u003e p)`: Defines a predicate that each pair of elements of the resultant list should hold.\n* `Var is(BiPredicate\u003cT, T\u003e p)`: Alias of the `Var holds(BiPredicate\u003cT, T\u003e p)` method.\n\n### Examples\n\nFilter a list of even numbers:\n```java\n// { x | x E {1,2,3,4,5} ^ x is-even }\n\nPredicate\u003cInteger\u003e isEven = x -\u003e x % 2 == 0;\nList\u003cInteger\u003e evens = new ListComprehension\u003cInteger\u003e()\n  .suchThat(s -\u003e {\n    s.belongsTo(Arrays.asList(1,2,3,4,5));\n    s.holds(isEven);\n  });\n```\n\nMap a list of numbers in order to have them duplicated:\n```java\n// { x*2 | x E {1,2,3,4,5} }\n\nList\u003cInteger\u003e duplicated = new ListComprehension\u003cInteger\u003e()\n  .outputExpression((Integer x) -\u003e x * 2)\n  .suchThat(s -\u003e {\n    s.belongsTo(Arrays.asList(1,2,3,4,5));\n});\n```\n\nMake the cartesian product of two lists and keep the pair of elements that hold that an element is the 2 times the other one: \n```java\n// { (x,y) | x E {1,2,3} ^ y E {4,5,6} ^ 2 * x = y }\n\nList\u003cPair\u003cInteger,Integer\u003e\u003e doublePairs = new ListComprehension\u003cInteger\u003e()\n  .suchThat((x, y) -\u003e {\n    x.belongsTo(Arrays.asList(1,2,3));\n    y.belongsTo(Arrays.asList(4,5,6));\n    x.holds((x, y) -\u003e x * 2 == y);\n});\n```\n\n### Motivation\nMy college project of Functional Programming at ITBA (Buenos Aires Institute of Technology): https://github.com/farolfo/list-comprehensions-in-java\n\n### Further reading\n\n* [Set-builder notation.](https://en.wikipedia.org/wiki/Set-builder_notation)\n* [How are programming languages supporting this today?](https://en.wikipedia.org/wiki/Comparison_of_programming_languages_(list_comprehension))\n* [Haskell's list comprehension](http://learnyouahaskell.com/starting-out#im-a-list-comprehension)\n\n### License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffarolfo%2Fjcomprehension","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffarolfo%2Fjcomprehension","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffarolfo%2Fjcomprehension/lists"}