{"id":20894626,"url":"https://github.com/applitopia/immutable-sorted","last_synced_at":"2025-06-13T17:37:57.211Z","repository":{"id":57272853,"uuid":"94913690","full_name":"applitopia/immutable-sorted","owner":"applitopia","description":"This is an extension of Immutable.js that provides sorted collections SortedMap and SortedSet. The current implementation is using highly optimized B-tree memory structure.","archived":false,"fork":false,"pushed_at":"2019-02-04T04:47:57.000Z","size":21040,"stargazers_count":29,"open_issues_count":3,"forks_count":6,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-12T23:36:21.609Z","etag":null,"topics":["b-tree","btree","immutable","incremental-sort","javascript","partial-sort","sorted-map","sorted-set"],"latest_commit_sha":null,"homepage":"http://applitopia.github.io/immutable-sorted/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/applitopia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-20T16:41:44.000Z","updated_at":"2023-09-08T17:26:36.000Z","dependencies_parsed_at":"2022-08-25T00:10:46.331Z","dependency_job_id":null,"html_url":"https://github.com/applitopia/immutable-sorted","commit_stats":null,"previous_names":[],"tags_count":76,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/applitopia%2Fimmutable-sorted","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/applitopia%2Fimmutable-sorted/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/applitopia%2Fimmutable-sorted/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/applitopia%2Fimmutable-sorted/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/applitopia","download_url":"https://codeload.github.com/applitopia/immutable-sorted/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/applitopia%2Fimmutable-sorted/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":258938844,"owners_count":22781012,"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":["b-tree","btree","immutable","incremental-sort","javascript","partial-sort","sorted-map","sorted-set"],"created_at":"2024-11-18T10:20:30.007Z","updated_at":"2025-06-13T17:37:57.163Z","avatar_url":"https://github.com/applitopia.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Immutable Sorted Collections for JavaScript\n===========================================\n[![npm version](https://badge.fury.io/js/immutable-sorted.svg)](https://badge.fury.io/js/immutable-sorted)\n[![jest](https://img.shields.io/badge/tested_with-jest-brightgreen.svg)](https://facebook.github.io/jest/)\n[![dependencies](https://img.shields.io/david/applitopia/immutable-sorted.svg)](https://david-dm.org/applitopia/immutable-sorted)\n[![devDependencies](https://img.shields.io/david/dev/applitopia/immutable-sorted.svg)](https://david-dm.org/applitopia/immutable-sorted?type=dev)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\nThis package is an extension of popular collections library [Immutable.js](https://github.com/facebook/immutable-js). It provides additional immutable collections [SortedMap](https://applitopia.github.io/immutable-sorted/docs/#/SortedMap) and [SortedSet](https://applitopia.github.io/immutable-sorted/docs/#/SortedSet) that maintain their entries sorted by a comparator. The current implementation is using a classic [B-tree](https://en.wikipedia.org/wiki/B-tree) memory structure.\n\nAdditionally, this package provides [partial sort](https://en.wikipedia.org/wiki/Partial_sorting) (returning the `n smallest elements`)\nand [incremental sort](https://en.wikipedia.org/wiki/Selection_algorithm#Incremental_sorting_by_selection)\noperations implemented using [Floyd-Rivest](https://en.wikipedia.org/wiki/Floyd%E2%80%93Rivest_algorithm) variant of [selection algorithm](https://en.wikipedia.org/wiki/Selection_algorithm).\n\nVersion\n-------\n\nThe current version [immutable-sorted@0.2.11](https://github.com/applitopia/immutable-sorted/releases/tag/v0.2.11) is an extension of [immutable-js@4.0.0-rc.12](https://github.com/facebook/immutable-js/releases/tag/v4.0.0-rc.12).\n\n\nInstallation\n------------\n\n```shell\nnpm install immutable-sorted\n```\n\nSortedSet\n---------\n\nSee more details on [SortedSet](https://applitopia.github.io/immutable-sorted/docs/#/SortedSet) page.\n\nSortedSet is a type of Set that keeps its values sorted by a comparator. The current implementation is using a classic B-Tree memory structure with O(N) space requirements and O(log N) get, add, and delete operations.\n\nExample:\n```js\n\u003e const { SortedSet } = require('immutable-sorted');\n\n\u003e const set1=SortedSet(['orange', 'apple', 'banana']);\nSortedSet { \"apple\", \"banana\", \"orange\" }\n\n\u003e const set2=set1.add('mango');\nSortedSet { \"apple\", \"banana\", \"mango\", \"orange\" }\n\n\u003e const set3=set2.delete('banana');\nSortedSet { \"apple\", \"mango\", \"orange\" }\n```\n\nUsing a custom comparator:\n\n```js\n\u003e const reverseCmp=(a,b)=\u003e(a\u003eb?-1:a\u003cb?1:0);\n\n\u003e const set4=SortedSet(set1, reverseCmp);\nSortedSet { \"orange\", \"banana\", \"apple\" }\n\n\u003e const set5=set4.add('mango');\nSortedSet { \"orange\", \"mango\", \"banana\", \"apple\" }\n\n\u003e const set6=set5.delete('banana');\nSortedSet { \"orange\", \"mango\", \"apple\" }\n```\n\nSet values, like Map keys, may be of any type. Equality is determined by comparator returning 0 value. In case of a custom comparator the equality may be redefined to have a different meaning than Immutable.is.\n\n**Searching SortedSet**\n\nMany real applications require ability to efficiently search in a sorted dataset. The method:\n\n```js\nfrom(value, backwards) \n```\n\nreturns a sequence that represents a subset of a sorted set starting with value \nup to the last element in the set.\n\nIf the optional parameter backwards is set to true, the returned sequence will\nlist the entries backwards, starting with value down to the first element in the set.\n\nExample:\n```js\nconst { SortedSet } = require('immutable-sorted');\n\nconst abc = SortedSet([\"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\", \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\", \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\"]);\n\n\u003e abc.from(\"R\");\nSeq { \"R\", \"S\", \"T\", \"U\", \"V\", \"W\", \"X\", \"Y\", \"Z\" }\n\n\u003e abc.from(\"R\", true);\nSeq { \"R\", \"Q\", \"P\", \"O\", \"N\", \"M\", \"L\", \"K\", \"J\", \"I\", \"H\", \"G\", \"F\", \"E\", \"D\", \"C\", \"B\", \"A\" }\n```\n\nThe method from() can be efficiently combined with take() to retrieve the desired number of values or with takeWhile() to retrieve a specific range:\n```js\n\u003e abc.from(\"R\").take(5);\nSeq { \"R\", \"S\", \"T\", \"U\", \"V\" }\n\n\u003e abc.from(\"R\").takeWhile(s =\u003e s \u003c \"W\");\nSeq { \"R\", \"S\", \"T\", \"U\", \"V\" }\n\n\u003e abc.from(\"R\", true).take(5);\nSeq { \"R\", \"Q\", \"P\", \"O\", \"N\" }\n\n\u003e abc.from(\"R\", true).takeWhile(s =\u003e s \u003e \"K\");\nSeq { \"R\", \"Q\", \"P\", \"O\", \"N\", \"M\", \"L\" }\n```\n\nWe can also use the numeric index to efficiently iterate through the sorted collections starting from numeric index as if they were arrays. The method:\n\n```js\nfromIndex(n, backwards) \n```\n\nis optimized to quickly find the n-th entry inside the b-tree structure by checking the computed sizes of underlying nodes. Even though the algorithm is not as fast as working with native array, it is faster by orders of magnitude than walking through the first n elements in unindexed collection to skip them. The access time is O(log N).\n\nExamples:\n```js\n\u003e abc.fromIndex(4).take(5);\nSeq { \"E\", \"F\", \"G\", \"H\", \"I\" }\n\n\u003e abc.fromIndex(4, true).take(5);\nSeq { \"E\", \"D\", \"C\", \"B\", \"A\" }\n```\n\n**Working with objects**\n\nMany real use cases will be about storing the whole objects in SortedSet. That will usually be meaningful only when custom comparator is defined.\n\nLet's consider the following example with city objects:\n\n```js\n\u003e const { SortedSet, Seq, fromJS } = require('immutable-sorted');\n\n// Have an array of city objects\n\u003e const cities=[\n   {state: 'MA', city: 'Boston'},\n   {city: 'Miami', state: 'FL'},\n   {city: 'Seattle', state: 'WA'},\n   {city: 'Phoenix', state: 'AZ'}];\n\n// Make a seq that converts cities from JS into immutable objects\n\u003e const citiesSeq=Seq(cities).map((v)=\u003efromJS(v));\n\n// Create a default SortedSet\n\u003e const set1=SortedSet(citiesSeq);\nSortedSet {\n   Map { \"city\": \"Miami\", \"state\": \"FL\" },\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" },\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" },\n   Map { \"state\": \"MA\", \"city\": \"Boston\" } }\n```\n\nWhen relying on defaultComparator, like in example above, the objects get sorted by their string representations from toString() method. This is usually not what the application designers want. In our case it makes more sense to sort by the city name, than the whole string representation.\n\nLet's create a custom comparator:\n\n```js\n// Define a general comparator\n\u003e const cmp=(a,b)=\u003e(a\u003eb?1:(a\u003cb?-1:0));\n\n// Define a comparator of city names\n\u003e let citiesCmp=(a,b)=\u003ecmp(a.get('city'), b.get('city'));\n\n// Create a SortedSet with custom comparator\n\u003e const set2=SortedSet(citiesSeq, citiesCmp);\nSortedSet {\n   Map { \"state\": \"MA\", \"city\": \"Boston\" },\n   Map { \"city\": \"Miami\", \"state\": \"FL\" },\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" },\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" } }\n```\n\nThe custom comparator that we have created seems to work as expected. Now let's add into the collection another city of Phoenix, this time from state Illinois.\n\n```js\n\u003e const set3=set2.add(fromJS({city: 'Phoenix', state: 'IL'}));\nSortedSet {\n   Map { \"state\": \"MA\", \"city\": \"Boston\" },\n   Map { \"city\": \"Miami\", \"state\": \"FL\" },\n   Map { \"city\": \"Phoenix\", \"state\": \"IL\" },\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" } }\n```\n\nThe Phoenix, AZ had been replaced with Phoenix, IL. This is because of the way the custom comparator is defined. It determines equality by comparing city names only, therefore Phoenix, AZ and Phoenix, IL are equal according to this comparator. Let's try to extend the comparator to compare the city name first and if they match then determine the result by comparing the state.\n\n```js\n// Define more complex custom comparator\n\u003e citiesCmp=(a,b)=\u003ecmp(a.get('city'), b.get('city'))||cmp(a.get('state'), b.get('state'));\n\n// Create a new SortedSet with new custom comparator\n\u003e const set4=SortedSet(set2, citiesCmp);\nSortedSet {\n   Map { \"state\": \"MA\", \"city\": \"Boston\" },\n   Map { \"city\": \"Miami\", \"state\": \"FL\" },\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" },\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" } }\n\n// set4 looks the same as set2, now let's add the conflicting Phoenix, IL to set4\n\u003e const set5=set4.add(fromJS({city: 'Phoenix', state: 'IL'}));\nSortedSet {\n   Map { \"state\": \"MA\", \"city\": \"Boston\" },\n   Map { \"city\": \"Miami\", \"state\": \"FL\" },\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" },\n   Map { \"city\": \"Phoenix\", \"state\": \"IL\" },\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" } }\n```\n\nThe custom comparator behaves as expected. Now let's swap the order of commands in the comparator and sort by state first and by city name second.\n\n```js\n\u003e const stateCitiesCmp=(a,b)=\u003ecmp(a.get('state'), b.get('state'))||cmp(a.get('city'), b.get('city'));\n\n\u003e const set6=SortedSet(set5, stateCitiesCmp);\nSortedSet {\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" },\n   Map { \"city\": \"Miami\", \"state\": \"FL\" },\n   Map { \"city\": \"Phoenix\", \"state\": \"IL\" },\n   Map { \"state\": \"MA\", \"city\": \"Boston\" },\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" } }\n```\n\nSortedMap\n---------\n\nSee more details on [SortedMap](https://applitopia.github.io/immutable-sorted/docs/#/SortedMap) page.\n\nSortedMap is a type of Map that keeps its entries (their keys) sorted by a comparator. The current implementation is using a classic B-Tree memory structure with O(N) space requirements and O(log N) get, set, and delete operations.\n\nExample:\n```js\nconst { SortedMap } = require('immutable-sorted');\n\n\u003e const map1=SortedMap([['orange','orange'], ['apple','red'], ['banana','yellow']]);\nSortedMap { \"apple\": \"red\", \"banana\": \"yellow\", \"orange\": \"orange\" }\n\n\u003e const map2=map1.set('mango', 'yellow/orange');\nSortedMap { \"apple\": \"red\", \"banana\": \"yellow\", \"mango\": \"yellow/orange\", \"orange\": \"orange\" }\n\n\u003e const map3=map2.delete('banana');\nSortedMap { \"apple\": \"red\", \"mango\": \"yellow/orange\", \"orange\": \"orange\" }\n```\n\nUsing a custom comparator:\n\n```js\n\u003e const reverseCmp=(a,b)=\u003e(a\u003eb?-1:(a\u003cb?1:0));\n\n\u003e const map4=SortedMap(map1, reverseCmp);\nSortedMap { \"orange\": \"orange\", \"banana\": \"yellow\", \"apple\": \"red\" }\n\n\u003e const map5=map4.set('mango', 'yellow/orange');\nSortedMap { \"orange\": \"orange\", \"mango\": \"yellow/orange\", \"banana\": \"yellow\", \"apple\": \"red\" }\n\n\u003e const map6=map5.delete('banana');\nSortedMap { \"orange\": \"orange\", \"mango\": \"yellow/orange\", \"apple\": \"red\" }\n```\n\nWhen iterating a SortedMap, the order of entries is guaranteed to be the same as the sorted order of keys determined by a comparator.\n\nMap keys and values may be of any type. Equality of keys is determined by comparator returning 0 value. In case of a custom comparator the equality may be redefined to have a different meaning than Immutable.is.\n\n**Searching SortedMap**\n\nMany real applications require ability to efficiently search in a sorted data structure. The method:\n\n```js\nfrom(key, backwards)\n```\n\nreturns a sequence that represents a portion of this sorted map starting with a specific key up to the last entry in the sorted  map.\n\nIf the optional parameter backwards is set to true, the returned sequence will list the entries backwards, starting with key down to the first entry in the sorted map.\n\nExample:\n```js\n\u003e const abc = SortedMap([[\"A\", \"a\"], [\"B\", \"b\"], [\"C\", \"c\"], [\"D\", \"d\"], [\"E\", \"e\"], [\"F\", \"f\"], [\"G\", \"g\"], [\"H\", \"h\"], [\"I\", \"i\"], [\"J\", \"j\"], [\"K\", \"k\"], [\"L\", \"l\"], [\"M\", \"m\"], [\"N\", \"n\"], [\"O\", \"o\"], [\"P\", \"p\"], [\"Q\", \"q\"], [\"R\", \"r\"], [\"S\", \"s\"], [\"T\", \"t\"], [\"U\", \"u\"], [\"V\", \"v\"], [\"W\", \"w\"], [\"X\", \"x\"], [\"Y\", \"y\"], [\"Z\", \"z\"]]);\n \n\u003e abc.from(\"R\");\nSeq { \"R\": \"r\", \"S\": \"s\", \"T\": \"t\", \"U\": \"u\", \"V\": \"v\", \"W\": \"w\", \"X\": \"x\", \"Y\": \"y\", \"Z\": \"z\" }\n \n\u003e abc.from(\"R\", true);\nSeq { \"R\": \"r\", \"Q\": \"q\", \"P\": \"p\", \"O\": \"o\", \"N\": \"n\", \"M\": \"m\", \"L\": \"l\", \"K\": \"k\", \"J\": \"j\", \"I\": \"i\", \"H\": \"h\", \"G\": \"g\", \"F\": \"f\", \"E\": \"e\", \"D\": \"d\", \"C\": \"c\", \"B\": \"b\", \"A\": \"a\" }\n```\n\nThe method from() can be efficiently combined with take() to retrieve the desired number of values or with takeWhile() to retrieve a specific range:\n```js\n\u003e abc.from(\"R\").take(5);\nSeq { \"R\": \"r\", \"S\": \"s\", \"T\": \"t\", \"U\": \"u\", \"V\": \"v\" }\n\n\u003e abc.from(\"R\").takeWhile((v, k) =\u003e k \u003c \"W\");\nSeq { \"R\": \"r\", \"S\": \"s\", \"T\": \"t\", \"U\": \"u\", \"V\": \"v\" }\n \n\u003e abc.from(\"R\", true).take(5);\nSeq { \"R\": \"r\", \"Q\": \"q\", \"P\": \"p\", \"O\": \"o\", \"N\": \"n\" }\n \n\u003e abc.from(\"R\", true).takeWhile((v, k) =\u003e k \u003e \"K\");\nSeq { \"R\": \"r\", \"Q\": \"q\", \"P\": \"p\", \"O\": \"o\", \"N\": \"n\", \"M\": \"m\", \"L\": \"l\" }\n```\n\n**Working with objects**\n\nMany real use cases will be about storing the whole objects in SortedMap. That will usually be meaningful only when custom comparator is defined.\n\nLet's consider the following example with city objects as keys and their co-ordinates as values:\n\n```js\n\u003e const { SortedMap, Seq, fromJS } = require('immutable-sorted');\n\n// Have an array of city objects\n\u003e const cities=[\n   [{state: 'MA', city: 'Boston'}, ['42°21′N','71°04′W']],\n   [{city: 'Miami', state: 'FL'},['25°47′N','80°13′W']],\n   [{city: 'Seattle', state: 'WA'},['47°37′N','122°20′W']],\n   [{city: 'Phoenix', state: 'AZ'},['33°27′N','112°04′W']]];\n\n// Make a seq that converts cities and their co-ordinates from JS into immutable objects\n\u003e const citiesSeq=Seq.Keyed(cities).mapKeys((v)=\u003efromJS(v)).map((v)=\u003efromJS(v));\nSeq {\n   Map { \"state\": \"MA\", \"city\": \"Boston\" }: List [ \"42°21′N\", \"71°04′W\" ],\n   Map { \"city\": \"Miami\", \"state\": \"FL\" }: List [ \"25°47′N\", \"80°13′W\" ],\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" }: List [ \"47°37′N\", \"122°20′W\" ],\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" }: List [ \"33°27′N\", \"112°04′W\" ] }\n\n// Create a default SortedMap\n\u003e const map1=SortedMap(citiesSeq);\nSortedMap {\n   Map { \"city\": \"Miami\", \"state\": \"FL\" }: List [ \"25°47′N\", \"80°13′W\" ],\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" }: List [ \"33°27′N\", \"112°04′W\" ],\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" }: List [ \"47°37′N\", \"122°20′W\" ],\n   Map { \"state\": \"MA\", \"city\": \"Boston\" }: List [ \"42°21′N\", \"71°04′W\" ] }\n```\n\nWhen relying on defaultComparator, like in example above, the objects get sorted by their string representations from toString() method. This is usually not what the application designers want. In our case it makes more sense to sort by the city name, than the whole string representation.\n\nLet's create a custom comparator:\n\n```js\n// Define a general simple comparator\n\u003e const cmp=(a,b)=\u003e(a\u003eb?1:(a\u003cb?-1:0));\n\n// Define a comparator of city names\n\u003e let citiesCmp=(a,b)=\u003ecmp(a.get('city'), b.get('city'));\n\n// Create a SortedSet with custom comparator\n\u003e const map2=SortedMap(citiesSeq, citiesCmp);\nSortedMap {\n   Map { \"state\": \"MA\", \"city\": \"Boston\" }: List [ \"42°21′N\", \"71°04′W\" ],\n   Map { \"city\": \"Miami\", \"state\": \"FL\" }: List [ \"25°47′N\", \"80°13′W\" ],\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" }: List [ \"33°27′N\", \"112°04′W\" ],\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" }: List [ \"47°37′N\", \"122°20′W\" ] }\n```\n\nThe custom comparator that we have created seems to work as expected. Now let's add into the collection another city of Phoenix, this time from state Illinois.\n\n```js\n\u003e const map3=map2.set(fromJS({city: 'Phoenix', state: 'IL'}), fromJS(['41°36′N','87°37′W']));\nSortedMap {\n   Map { \"state\": \"MA\", \"city\": \"Boston\" }: List [ \"42°21′N\", \"71°04′W\" ],\n   Map { \"city\": \"Miami\", \"state\": \"FL\" }: List [ \"25°47′N\", \"80°13′W\" ],\n   Map { \"city\": \"Phoenix\", \"state\": \"IL\" }: List [ \"41°36′N\", \"87°37′W\" ],\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" }: List [ \"47°37′N\", \"122°20′W\" ] }\n```\n\nThe Phoenix, AZ had been replaced with Phoenix, IL. This is because of the way the custom comparator is defined. It determines equality by comparing city names only, therefore Phoenix, AZ and Phoenix, IL are equal according to this comparator. Let's try to extend the comparator to compare the city name first and if they match then determine the result by comparing the state.\n\n```js\n// Define more complex custom comparator\n\u003e citiesCmp=(a,b)=\u003ecmp(a.get('city'), b.get('city'))||cmp(a.get('state'), b.get('state'));\n\n// Create a new SortedMap with new custom comparator\n\u003e const map4=SortedMap(map2, citiesCmp);\nSortedMap {\n   Map { \"state\": \"MA\", \"city\": \"Boston\" }: List [ \"42°21′N\", \"71°04′W\" ],\n   Map { \"city\": \"Miami\", \"state\": \"FL\" }: List [ \"25°47′N\", \"80°13′W\" ],\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" }: List [ \"33°27′N\", \"112°04′W\" ],\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" }: List [ \"47°37′N\", \"122°20′W\" ] }\n\n// map4 looks the same as map2, now let's add the conflicting Phoenix, IL to map4\n\u003e const map5=map4.set(fromJS({city: 'Phoenix', state: 'IL'}), fromJS(['41°36′N','87°37′W']));\nSortedMap {\n   Map { \"state\": \"MA\", \"city\": \"Boston\" }: List [ \"42°21′N\", \"71°04′W\" ],\n   Map { \"city\": \"Miami\", \"state\": \"FL\" }: List [ \"25°47′N\", \"80°13′W\" ],\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" }: List [ \"33°27′N\", \"112°04′W\" ],\n   Map { \"city\": \"Phoenix\", \"state\": \"IL\" }: List [ \"41°36′N\", \"87°37′W\" ],\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" }: List [ \"47°37′N\", \"122°20′W\" ] }\n```\n\nThe custom comparator behaves as expected. Now let's swap the order of commands in the comparator and sort by state first and by city name second.\n\n```js\n\u003e const stateCitiesCmp=(a,b)=\u003ecmp(a.get('state'), b.get('state'))||cmp(a.get('city'), b.get('city'));\n\n\u003e const map6=SortedMap(map5, stateCitiesCmp);\nSortedMap {\n   Map { \"city\": \"Phoenix\", \"state\": \"AZ\" }: List [ \"33°27′N\", \"112°04′W\" ],\n   Map { \"city\": \"Miami\", \"state\": \"FL\" }: List [ \"25°47′N\", \"80°13′W\" ],\n   Map { \"city\": \"Phoenix\", \"state\": \"IL\" }: List [ \"41°36′N\", \"87°37′W\" ],\n   Map { \"state\": \"MA\", \"city\": \"Boston\" }: List [ \"42°21′N\", \"71°04′W\" ],\n   Map { \"city\": \"Seattle\", \"state\": \"WA\" }: List [ \"47°37′N\", \"122°20′W\" ] }\n  ```\n\nPartial sort\n------------\n\nAny collection (including sequences) provides partialSort() and partialSortBy()\nfunctions for efficiently finding and sorting the `n smallest elements` in a collection using\nFloyd-Rivest select algorithm.\n\nExample:\n```js\n\u003e const { Seq } = require('immutable-sorted');\n\n\u003e const seq1=Seq(['orange', 'apple', 'banana']);\n\u003e seq1.partialSort(2)\nSeq [ \"apple\", \"banana\" ]\n```\n\nIncremental sort\n----------------\n\nAny collection (including sequences) also provides incSort() and incSortBy()\nfunctions optimized to provide first entries of the result set faster than regular sort().\nThis function is expected to be used with iterators or sequence operations\nretrieving limited number of result entries.\n\nExample:\n```js\n\u003e const { Seq } = require('immutable-sorted');\n\n\u003e const seq1=Seq(['orange', 'apple', 'banana']);\n\u003e seq1.incSort().take(2)\nSeq [ \"apple\", \"banana\" ]\n```\n\nLicense\n-------\n\nMIT License\n\nModified work Copyright (c) 2017-present, Applitopia, Inc.\n\nOriginal work Copyright (c) 2014-present, Facebook, Inc.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapplitopia%2Fimmutable-sorted","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapplitopia%2Fimmutable-sorted","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapplitopia%2Fimmutable-sorted/lists"}