{"id":18485366,"url":"https://github.com/arturopala/buffer-and-slice","last_synced_at":"2025-04-08T19:32:32.255Z","repository":{"id":57719551,"uuid":"259341072","full_name":"arturopala/buffer-and-slice","owner":"arturopala","description":"Lightweight Buffer and Slice abstractions for Scala.","archived":false,"fork":false,"pushed_at":"2024-02-24T00:26:18.000Z","size":2039,"stargazers_count":25,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-05-09T07:11:04.652Z","etag":null,"topics":["array","collection","data-structures","scala","slice"],"latest_commit_sha":null,"homepage":null,"language":"Scala","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arturopala.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}},"created_at":"2020-04-27T14:03:16.000Z","updated_at":"2023-03-28T16:02:26.000Z","dependencies_parsed_at":"2022-09-02T13:10:46.692Z","dependency_job_id":null,"html_url":"https://github.com/arturopala/buffer-and-slice","commit_stats":null,"previous_names":[],"tags_count":72,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arturopala%2Fbuffer-and-slice","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arturopala%2Fbuffer-and-slice/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arturopala%2Fbuffer-and-slice/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arturopala%2Fbuffer-and-slice/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arturopala","download_url":"https://codeload.github.com/arturopala/buffer-and-slice/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223342801,"owners_count":17129927,"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":["array","collection","data-structures","scala","slice"],"created_at":"2024-11-06T12:44:58.763Z","updated_at":"2024-11-06T12:44:58.861Z","avatar_url":"https://github.com/arturopala.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"![Build](https://github.com/arturopala/buffer-and-slice/workflows/Build/badge.svg) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.arturopala/buffer-and-slice_2.13/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.github.arturopala/buffer-and-slice_2.13)\n[![Scala.js](https://www.scala-js.org/assets/badges/scalajs-1.12.0.svg)](https://www.scala-js.org)\n![Code size](https://img.shields.io/github/languages/code-size/arturopala/buffer-and-slice)\n![GitHub](https://img.shields.io/github/license/arturopala/buffer-and-slice)\n![Lift](https://lift.sonatype.com/api/badge/github.com/arturopala/buffer-and-slice)\n\nBuffer\\[T] and Slice\\[T]\n===\n\nThis is a micro-library for Scala providing lightweight Buffer and Slice abstractions.\n\n    \"com.github.arturopala\" %% \"buffer-and-slice\" % \"1.63.0\"\n\nCross-compiles to Scala versions `2.13.12`, `2.12.18`, `3.3.1`, \nand ScalaJS version `1.14.0`, and ScalaNative version `0.4.15`.\n\nMotivation\n---\n\nWorking directly with mutable arrays, even in Scala, is not always as simple and efficient as it could be. \nWhile `Array` features Scala Collections API, the first reason to use arrays is to fully exploit its compactness and mutability\nfor performance reasons. I've found it reasonable to have a separate, focused set of low-overhead tools dealing with an `Array`.\n\nAnother concern was a proliferation of `ClassTag` context parameter, \nmaking it hard to offer Array-based variants of a generic data-structures.\nThis API requires now `ClassTag` only for explicit `.toArray[T1 \u003e: T]` call, nowhere else.\n\nWhy at all using arrays in the era of functional programming?\n---\n\nArrays are the most primitive but very efficient data structures, with fast access time, \ncompact representation, unbeatable copy performance and taking advantage of the CPU cache line. \n\nThe FP solution is to exploit arrays but avoid sharing its mutable state around. \nThis is where the `Buffer` and the `Slice` concept fits in.\n\nDesign\n---\n\nThis library provides two complementary abstractions, two sides of the coin: mutable `Buffer` and immutable lazy `Slice`.\n\n- A `Buffer` role is to help easily build a growable array using mixed buffer- and stack- like APIs.\n\n- A `Slice` role is to share an immutable slice of the array.\n\nThe usual workflow will use `Buffer` to build an array and `Slice` to share the result outside of a component/function.\n\nBoth `Buffer` and `Slice` come in variants: \n\n- generic `ArrayBuffer[T]` and `ArraySlice[T]`, \n- specialized `IntBuffer` and `IntSlice` with additional numeric API, \n- specialized `ByteBuffer` and `ByteSlice`.\n- `LazyMapArraySlice` provides very light mapping operation on `Slice` without forcing underlying array copy.\n- `RangeMapSlice` provides a slice of function of integers.\n- `DeferredArrayBuffer[T]` makes it possible to defer underlying array type decision for abstract types.\n\nDependencies\n---\n\nDepends only on a standard built-in Scala library.\n\nAPI\n---\n\n`Buffer` offers comprehensive API, together with `Stack`- and `List`- like interfaces.\n\nFor the purpose of using as a mutable List, the top element is a `head`.\n\nFor more details, see:\n\n- [Scaladoc of Buffer](https://arturopala.github.io/buffer-and-slice/latest/api/com/github/arturopala/bufferandslice/Buffer.html).\n- [Scaladoc of Slice](https://arturopala.github.io/buffer-and-slice/latest/api/com/github/arturopala/bufferandslice/Slice.html).\n\nPerformance\n---\n\nThe principle of this library is to avoid creating intermediary arrays as much as possible, \nand use native `java.lang.System.arraycopy` and `java.util.Arrays.copyOf` where applicable.\n\nLightweight operations:\n\n- creating new `Buffer` or `Slice` from an array\n- slicing (`asSlice`, `slice`, `take`, `drop`, `takeRight`, `dropRight`)\n- mapping the slice\n- using iterators or `toIterable`\n- making `Slice.copyToArray`\n- subsequent detaching\n\nHeavier operations, making a copy of an array:\n\n- detaching a slice first-time, if not detached already\n- updating a slice\n- making a copy of a buffer\n- exporting slice or buffer (`toArray`, `toList`, `toBuffer`)\n\nE.g. the following code makes no copy of an array `a`:\n\n```scala\nimport com.github.arturopala.bufferandslice._\n\nval a = Array.fill(1000)(1)\nval buffer = Buffer(a,100)\nval slice1 = buffer.slice(13,31).map(_ * 2)\nbuffer.insertSlice(23, slice1.map(_ * 3))\nbuffer.replaceFromSlice(87, slice1.drop(7))\nval slice2 = buffer.slice(17,71)\nslice2.map(_+10).iterator.mkString(\"[\",\",\",\"]\")\nbuffer.appendSlice(slice2)\n```\n\nIndex tracking\n--\n\nBuffer manipulations, like `shift..`, `move..`, or `swap..` can change the buffer layout in a complex way.\n\nAn `IndexTracker` object provides set of functions to keep your external index buffer or list in sync with those changes.\n\nExamples\n---\n\nBuffer\n---\n\n[Open in Scastie](https://scastie.scala-lang.org/arturopala/AeuggR2xTYC4lpNWLZoyug/6)\n\n```scala\nimport com.github.arturopala.bufferandslice._\n\nBuffer.empty[String]\n// res4: Buffer[String] = []\n\nBuffer.empty[Double]\n// res5: Buffer[Double] = []\n\nBuffer.empty[Int]\n// res6: Buffer[Int] = []\n\nBuffer.empty[Byte]\n// res7: Buffer[Byte] = []\n\nBuffer(\"a\",\"b\",\"c\")\n// res8: Buffer[String] = [a,b,c]\n\nBuffer(Array(\"a\",\"b\",\"c\"))\n// res9: Buffer[String] = [a,b,c]\n\nBuffer(1,2,3).apply(1)\n// res10: Int = 2\n\nBuffer(1,2,3).get(2)\n// res11: Option[Int] = Some(value = 3)\n\nBuffer(\"a\",\"b\",\"c\").head\n// res12: String = \"c\"\n\nBuffer(\"a\",\"b\",\"c\").last\n// res13: String = \"a\"\n\nBuffer(\"a\",\"b\",\"c\").tail\n// res14: Buffer[String] = [a,b]\n\nBuffer(\"a\",\"b\",\"c\").init\n// res15: Buffer[String] = [b,c]\n\nBuffer(1,2,3,4,5,6,7,8,9).asSlice\n// res16: Slice[Int] = Slice(1,2,3,4,5,6,7,8,9)\n\nBuffer(1,2,3,4,5,6,7,8,9).toArray\n// res17: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)\n\nBuffer(1d,2d,3d,4d,5d,6d,7d,8d,9d).asArray\n// res18: Array[Double] = Array(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)\n\nval b1 = ByteBuffer(1,2)\n// b1: ByteBuffer = [1,2]\n\nb1.copy.append(3)\n// res19: ByteBuffer = [1,2,3]\n\nb1.copy.append(4)\n// res20: ByteBuffer = [1,2,4]\n\nb1.emptyCopy.append(9)\n// res21: ByteBuffer = [9]\n```\n\n- Specialized `IntBuffer`:\n\n```scala\nIntBuffer(0,1,2,3)\n// res22: IntBuffer = [0,1,2,3]\n\nIntBuffer(Array(0,1,2,3))\n// res23: IntBuffer = [0,1,2,3]\n\nIntBuffer(0,1,2,3).asSlice\n// res24: IntSlice = Slice(0,1,2,3)\n```\n\n- Specialized `ByteBuffer`:\n\n```scala\nByteBuffer(0,1,2,3)\n// res25: ByteBuffer = [0,1,2,3]\n\nByteBuffer(Array(0,1,2,3).map(_.toByte))\n// res26: ByteBuffer = [0,1,2,3]\n\nByteBuffer(0,1,2,3).asSlice\n// res27: ByteSlice = Slice(0,1,2,3)\n```\n\n- Modifying the content:\n\n```scala\nByteBuffer(1,2,3).update(1,0)\n// res28: ByteBuffer = [1,0,3]\n\nBuffer(0,0,0).modify(1,_ + 1)\n// res29: Buffer[Int] = [0,1,0]\n\nBuffer(\"c\").append(\"a\")\n// res30: Buffer[String] = [c,a]\n\nBuffer(\"x\",\"y\",\"z\").insert(1,\"a\")\n// res31: Buffer[String] = [x,a,y,z]\n\nBuffer(\"a\",\"b\",\"c\").remove(1)\n// res32: Buffer[String] = [a,c]\n\nIntBuffer(0,1,1).appendSlice(Slice(0,1,2,3))\n// res33: IntBuffer = [0,1,1,0,1,2,3]\n\nIntBuffer(0,1,1).appendArray(Array(0,1,2,3))\n// res34: IntBuffer = [0,1,1,0,1,2,3]\n\nBuffer(\"a\").appendSequence(IndexedSeq(\"a\",\"a\",\"a\"))\n// res35: Buffer[String] = [a,a,a,a]\n\nBuffer(0).appendIterable(1 to 10)\n// res36: Buffer[Int] = [0,1,2,3,4,5,6,7,8,9,10]\n\nBuffer(\"b\").appendFromIterator(Iterator.fill(10)(\"a\"))\n// res37: Buffer[String] = [b,a,a,a,a,a,a,a,a,a,a]\n\nBuffer(\"b\").appendFromIterator(3, Iterator.fill(10)(\"a\"))\n// res38: Buffer[String] = [b,a,a,a]\n\nBuffer(0,0,0).insertValues(1,2,3,List(0,1,2,3,4,5))\n// res39: Buffer[Int] = [0,2,3,4,0,0]\n\nBuffer(0,0,0).insertFromIterator(2, 3, (1 to 7).iterator)\n// res40: Buffer[Int] = [0,0,1,2,3,0]\n\nBuffer(0,0,0).insertFromIterator(2, (1 to 7).iterator)\n// res41: Buffer[Int] = [0,0,1,2,3,4,5,6,7,0]\n\nBuffer(0,0,0).insertFromIteratorReverse(1, 5, (1 to 7).iterator)\n// res42: Buffer[Int] = [0,5,4,3,2,1,0,0]\n\nBuffer(0,0,0).insertFromIteratorReverse(1, (1 to 7).iterator)\n// res43: Buffer[Int] = [0,7,6,5,4,3,2,1,0,0]\n\nBuffer(\"a\",\"b\",\"c\").insertSlice(1, Slice(\"e\",\"f\"))\n// res44: Buffer[String] = [a,e,f,b,c]\n\nBuffer(0,0,0).insertArray(1,2,3,Array(0,1,2,3,4,5))\n// res45: Buffer[Int] = [0,2,3,4,0,0]\n\nBuffer(\"a\",\"b\",\"c\",\"d\",\"e\",\"f\").replaceFromSlice(4,Slice(\"a\",\"b\",\"c\"))\n// res46: Buffer[String] = [a,b,c,d,a,b,c]\n\nBuffer(0,0,0).replaceValues(1,2,3,List(0,1,2,3,4,5))\n// res47: Buffer[Int] = [0,2,3,4]\n\nBuffer(0,0,0).replaceFromIterator(2,3, (1 to 7).iterator)\n// res48: Buffer[Int] = [0,0,1,2,3]\n\nBuffer(0,0,0,0,0,0,0).replaceFromIteratorReverse(5,3, (1 to 7).iterator)\n// res49: Buffer[Int] = [0,0,0,0,0,3,2,1]\n\nBuffer(0,0,0).replaceFromArray(1,2,3,Array(0,1,2,3,4,5))\n// res50: Buffer[Int] = [0,2,3,4]\n\nBuffer(\"a\",\"b\",\"c\",\"d\",\"e\").removeRange(1,4)\n// res51: Buffer[String] = [a,e]\n\nBuffer(1,2,3,5,6).mapInPlace(_ * 2)\n// res52: Buffer[Int] = [2,4,6,10,12]\n\nBuffer(1,2,3,5,6).modifyAll(_ + 1)\n// res53: Buffer[Int] = [2,3,4,6,7]\n\nBuffer(1,2,3,5,6).modifyAllWhen(_ + 1, _ % 2 == 0)\n// res54: Buffer[Int] = [1,3,3,5,7]\n\nBuffer(0,0,0,0,0).modifyRange(1, 3, _ + 1)\n// res55: Buffer[Int] = [0,1,1,0,0]\n\nBuffer(1,2,3,4,5).modifyRangeWhen(1, 3, _ + 1, _ % 2 != 0)\n// res56: Buffer[Int] = [1,2,4,4,5]\n\nIntBuffer(1,2,3,4,5,6,7,8,9).shiftLeft(5,3)\n// res57: IntBuffer = [1,2,6,7,8,9]\n\nBuffer(1,2,3,4,5,6,7,8,9).shiftRight(5,3)\n// res58: Buffer[Int] = [1,2,3,4,5,6,7,8,6,7,8,9]\n\nBuffer(1,2,3,4,5,6,7,8,9).moveRangeRight(1,4,3)\n// res59: Buffer[Int] = [1,5,6,7,2,3,4,8,9]\n\nBuffer(1,2,3,4,5,6,7,8,9).moveRangeLeft(6,8,4)\n// res60: Buffer[Int] = [1,2,7,8,3,4,5,6,9]\n\nBuffer(1,2,3,4).swap(0,3)\n// res61: Buffer[Int] = [4,2,3,1]\n\nBuffer(1,2,3,4,5,6,7,8,9).swapRange(0,5,3)\n// res62: Buffer[Int] = [6,7,8,4,5,1,2,3,9]\n\nBuffer(1,2,3,4,5,6,7,8,9).contains(7)\n// res63: Boolean = true\n\nBuffer(1,2,3,4,5,6,7,8,9).exists(_ \u003e 8)\n// res64: Boolean = true\n\nBuffer(1,2,3,4,5,6,7,8,9).exists(_ \u003c 0)\n// res65: Boolean = false\n```\n\n- Using `Buffer` as a stack:\n\n```scala\nBuffer(1,2,3).peek\n// res66: Int = 3\n\nBuffer(1,2,3).peek(1)\n// res67: Int = 2\n\nBuffer(1,2,3).peekOption(2)\n// res68: Option[Int] = Some(value = 1)\n\nBuffer(1,2,3).peekOption(3)\n// res69: Option[Int] = None\n\nBuffer(1,2,3).pop\n// res70: Int = 3\n\nBuffer(1,2,3).push(1).push(1).push(0)\n// res71: Buffer[Int] = [1,2,3,1,1,0]\n```\n\n- Manipulating `topIndex` limit:\n\n```scala\nBuffer(1,2,3).top\n// res72: Int = 2\n\nBuffer(1,2,3).set(1)\n// res73: Buffer[Int] = [1,2]\n\nBuffer(1,2,3).forward(3)\n// res74: Buffer[Int] = [1,2,3,0,0,0]\n\nBuffer(1,2,3).rewind(2)\n// res75: Buffer[Int] = [1]\n\nBuffer(1,2,3).reset\n// res76: Int = 2\n```\n\n- Making a `Slice` of a `Buffer`:\n\n```scala\nBuffer(1,2,3,4,5,6,7,8,9).asSlice\n// res77: Slice[Int] = Slice(1,2,3,4,5,6,7,8,9)\n\nBuffer(1,2,3,4,5,6,7,8,9).slice(2,6)\n// res78: Slice[Int] = Slice(3,4,5,6)\n\nBuffer(\"a\",\"c\",\"e\").asSlice\n// res79: Slice[String] = Slice(a,c,e)\n\nBuffer(\"a\",\"c\",\"e\",\"d\",\"b\").slice(2,6)\n// res80: Slice[String] = Slice(e,d,b)\n```\n\n- Accessing buffer content\n\n```scala\nBuffer(\"a\",\"c\",\"e\").toArray\n// res81: Array[String] = Array(\"a\", \"c\", \"e\")\n\nBuffer(\"a\",\"c\",\"e\").asSlice.toList\n// res82: List[String] = List(\"a\", \"c\", \"e\")\n\nBuffer(1,2,3,4,5,6,7,8,9).iterator\n// res83: Iterator[Int] = non-empty iterator\n\nBuffer(1,2,3,4,5,6,7,8,9).reverseIterator\n// res84: Iterator[Int] = non-empty iterator\n\nval s = \"abscdefghijklmnopqrstuvxyz\"\n// s: String = \"abscdefghijklmnopqrstuvxyz\"\n\nBuffer(1,2,3,4,5,6,7,8,9).map(s.apply).toList\n// res85: List[Char] = List('b', 's', 'c', 'd', 'e', 'f', 'g', 'h', 'i')\n```\n\n\nSlice\n--\n\n[Open in Scastie](https://scastie.scala-lang.org/arturopala/jo2JWppuRRyCkYL3SjmS7A/3)\n\n```scala\nimport com.github.arturopala.bufferandslice._\n\nval array = Array(\"a\",\"b\",\"c\",\"d\",\"ee\",\"f\",\"g\",\"h\",\"i\",\"j\")\n// array: Array[String] = Array(\"a\", \"b\", \"c\", \"d\", \"ee\", \"f\", \"g\", \"h\", \"i\", \"j\")\n\nval slice = Slice.of(array)\n// slice: Slice[String] = Slice(a,b,c,d,ee,f,g,h,i,j)\n\nslice.length\n// res86: Int = 10\n\nslice.top\n// res87: Int = 9\n\nslice.apply(0)\n// res88: String = \"a\"\n\nslice.apply(5)\n// res89: String = \"f\"\n\nslice.get(0)\n// res90: Option[String] = Some(value = \"a\")\n\nslice.get(50)\n// res91: Option[String] = None\n\nslice.update(4,\"a\")\n// res92: Slice[String] = Slice(a,b,c,d,a,f,g,h,i,j)\n\nslice.update(5,\"b\")\n// res93: Slice[String] = Slice(a,b,c,d,ee,b,g,h,i,j)\n\nslice.slice(1,5)\n// res94: Slice[String] = Slice(b,c,d,ee)\n\nslice.take(5)\n// res95: Slice[String] = Slice(a,b,c,d,ee)\n\nslice.drop(5)\n// res96: Slice[String] = Slice(f,g,h,i,j)\n\nslice.takeRight(5)\n// res97: Slice[String] = Slice(f,g,h,i,j)\n\nslice.dropRight(5)\n// res98: Slice[String] = Slice(a,b,c,d,ee)\n\nslice.slice(2,6)\n// res99: Slice[String] = Slice(c,d,ee,f)\n\nslice.head\n// res100: String = \"a\"\n\nslice.headOption\n// res101: Option[String] = Some(value = \"a\")\n\nslice.init\n// res102: Slice[String] = Slice(a,b,c,d,ee,f,g,h,i)\n\nslice.last\n// res103: String = \"j\"\n\nslice.find(\"slice\".contains)\n// res104: Option[String] = Some(value = \"c\")\n\nslice.exists(\"slice\".contains)\n// res105: Boolean = true\n\nslice.map(s =\u003e s+s)\n// res106: Slice[String] = Slice(aa,bb,cc,dd,eeee,ff,gg,hh,ii,jj)\n\nslice.map(s =\u003e s\"($s)\")\n// res107: Slice[String] = Slice((a),(b),(c),(d),(ee),(f),(g),(h),(i),(j))\n\nslice.asIterable\n// res108: Iterable[String] = Iterable(\"a\", \"b\", \"c\", \"d\", \"ee\", \"f\", \"g\", \"h\", \"i\", \"j\")\n\nslice.iterator.toList\n// res109: List[String] = List(\"a\", \"b\", \"c\", \"d\", \"ee\", \"f\", \"g\", \"h\", \"i\", \"j\")\n\nslice.indexIterator(\"abeij\".contains(_)).toList\n// res110: List[Int] = List(0, 1, 8, 9)\n\nslice.iterator(\"abeij\".contains(_)).toList\n// res111: List[String] = List(\"a\", \"b\", \"i\", \"j\")\n\nslice.reverseIterator.toList\n// res112: List[String] = List(\"j\", \"i\", \"h\", \"g\", \"f\", \"ee\", \"d\", \"c\", \"b\", \"a\")\n\nslice.reverseIndexIterator(\"adgh\".contains(_)).toList\n// res113: List[Int] = List(7, 6, 3, 0)\n\nslice.reverseIterator(\"adgh\".contains(_)).toList\n// res114: List[String] = List(\"h\", \"g\", \"d\", \"a\")\n\nslice.toList\n// res115: List[String] = List(\"a\", \"b\", \"c\", \"d\", \"ee\", \"f\", \"g\", \"h\", \"i\", \"j\")\n\nslice.toSeq\n// res116: Seq[String] = Vector(\"a\", \"b\", \"c\", \"d\", \"ee\", \"f\", \"g\", \"h\", \"i\", \"j\")\n\nslice.toArray\n// res117: Array[String] = Array(\"a\", \"b\", \"c\", \"d\", \"ee\", \"f\", \"g\", \"h\", \"i\", \"j\")\n\nslice.copyToArray(3, new Array[String](15))\n// res118: Array[String] = Array(null, null, null, \"a\", \"b\", \"c\", \"d\", \"ee\", \"f\", \"g\", \"h\", \"i\", \"j\", null, null)\n\nslice.toBuffer\n// res119: Buffer[String] = [a,b,c,d,ee,f,g,h,i,j]\n\nslice.asBuffer\n// res120: Buffer[String] = [a,b,c,d,ee,f,g,h,i,j]\n\nval detached = slice.detach\n// detached: Slice[String] = Slice(a,b,c,d,ee,f,g,h,i,j)\n```\n\n- Aggregating a `Slice`:\n\n```scala\nval slice3 = Slice.of(\"abcdefghijklmno\".split(\"\"))\n// slice3: Slice[String] = Slice(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)\n\nslice3.fold(\"---\")(_ + _)\n// res121: String = \"---abcdefghijklmno\"\n\nslice3.reduce(_ + _)\n// res122: String = \"abcdefghijklmno\"\n\nval slice4 = IntSlice(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)\n// slice4: IntSlice = Slice(0,1,2,3,4,5,6,7,8,9)\n\nslice4.sum\n// res123: Int = 45\n\nslice4.min\n// res124: Int = 0\n\nslice4.max\n// res125: Int = 9\n\nslice4.reduce(_ + _)\n// res126: Int = 45\n\nslice4.fold(10)(_ + _)\n// res127: Int = 55\n\nslice4.foldLeft(10)(_ + _)\n// res128: Int = 55\n\nslice4.foldRight(10)(_ + _)\n// res129: Int = 55\n\nslice4.foldLeft(\"---\")(_ + _.toString)\n// res130: String = \"---0123456789\"\n\nslice4.foldRight(\"---\")(_.toString + _)\n// res131: String = \"0123456789---\"\n\nRangeMapSlice(x =\u003e s\"($x)\").take(10).drop(3).toList\n// res132: List[String] = List(\"(3)\", \"(4)\", \"(5)\", \"(6)\", \"(7)\", \"(8)\", \"(9)\")\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farturopala%2Fbuffer-and-slice","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farturopala%2Fbuffer-and-slice","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farturopala%2Fbuffer-and-slice/lists"}