{"id":15764543,"url":"https://github.com/pavkam/abacaxi","last_synced_at":"2025-06-13T14:08:56.535Z","repository":{"id":80062311,"uuid":"86197282","full_name":"pavkam/abacaxi","owner":"pavkam","description":"A library of various algorithms, helper classes and extension methods.","archived":false,"fork":false,"pushed_at":"2019-05-17T10:59:35.000Z","size":1196,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-09T14:04:27.500Z","etag":null,"topics":["algorithm","helpers-library"],"latest_commit_sha":null,"homepage":"","language":"C#","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/pavkam.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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":"2017-03-26T00:26:46.000Z","updated_at":"2023-09-30T06:43:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"ff94c3fd-6e95-4c12-b953-61aef2e54524","html_url":"https://github.com/pavkam/abacaxi","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/pavkam%2Fabacaxi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavkam%2Fabacaxi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavkam%2Fabacaxi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pavkam%2Fabacaxi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pavkam","download_url":"https://codeload.github.com/pavkam/abacaxi/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249996108,"owners_count":21358064,"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":["algorithm","helpers-library"],"created_at":"2024-10-04T12:04:03.809Z","updated_at":"2025-04-21T04:31:47.626Z","avatar_url":"https://github.com/pavkam.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Abacaxi [![Build status](https://ci.appveyor.com/api/projects/status/ckq7nanjy3nms8a7?svg=true)](https://ci.appveyor.com/project/pavkam/abacaxi)\n\n*\"No code library is complete without a binary search!\"*\n\nA library and repository of algorithms, data structures and helper methods that make one's daily programming life easier (in .NET that is).\n\nAbacaxi is available on NuGet: https://www.nuget.org/packages/Abacaxi/ and is built against __.NET Standard 2.0__ and __.NET 4.5__.\n\n### F# Support:\n\nF# bindings are available in the **Abacaxi.FSharp** library (targets __.NET Standard 2.0__ only). \n\nNote that not all C# methods have F# bindings since F# core library already contains comparable implementations. Also, some methods in F# do not make sense in C# world as well.\n\n### The list of core data structures:\n| Data structure | Description |\n| :--- | :--- |\n| `Heap` | Implements the *heap* data structure (also known as *priority queue*). Related material: \u003chttps://en.wikipedia.org/wiki/Heap_(data_structure)\u003e |\n| `MeanHeap` | Helper class that uses two *heaps* to provide O(1) mean value access to a sequence. Related material: \u003chttps://en.wikipedia.org/wiki/Heap_(data_structure)\u003e |\n| `BitSet` | Implements the standard *ISet\u0026lt;int\u0026gt;* data structure in an optimized form (using bit masks). Related material: \u003chttps://en.wikipedia.org/wiki/Bit_array\u003e |\n| `DisjointSet` | Also known as *union-find* or *merge-find* data structure. Related material: \u003chttps://en.wikipedia.org/wiki/Disjoint-set_data_structure\u003e |\n| `LinkedLinkedNode` | Represents a node in a *singly-linked list*. All operations implemented by the node classes. Related material: \u003chttps://en.wikipedia.org/wiki/Linked_list\u003e |\n| `Trie` | A *trie* that implements the *IDictionary\u0026lt;TKey, TValue\u0026gt;* interface. Related material: \u003chttps://en.wikipedia.org/wiki/Trie\u003e |\n| `AvlTree` | The standard *AVL self-balancing tree*. Related material: \u003chttps://en.wikipedia.org/wiki/AVL_tree\u003e |\n| `BinarySearchTree` | The standard *binary search tree*. Related material: \u003chttps://en.wikipedia.org/wiki/Binary_search_tree\u003e |\n| `LeftLeaningRedBlackTree` | The simplified version of *Red/Black self-balancing tree*. Related material: \u003chttps://en.wikipedia.org/wiki/Left-leaning_red%E2%80%93black_tree\u003e |\n| `Graph` | A generic *(un)directional weighted graph* that implements many algorithms. Related material: \u003chttps://en.wikipedia.org/wiki/Graph\u003e |\n| `ChessHorsePathGraph` | A specialized graph implementation used to solve the *Knight's Tour* problem. Related material: \u003chttps://en.wikipedia.org/wiki/Knight%27s_tour\u003e |\n| `StringNeighborhoodGraph` | A specialized graph implementation used to solve the *Word Ladder* problem. Related material: \u003chttps://en.wikipedia.org/wiki/Word_ladder\u003e |\n| `MazeGraph` | A specialized base class for other graphs that use a two-dimensional integer board (think, a rat's maze). All standard graph algorithms can be applied to such a graph. |\n| `LiteralGraph` | A specialized graph used mainly in testing the graph-related algorithms. |\n| `Mash` | The Swiss army knife of collections. In essence, a tree-like dictionary which can have other sub-dictionaries as children and store a list of items as leaves. Employs some techniques to avoid wasting unnecessary memory. |\n\n### The list of helper/additional classes:\n| Class | Description |\n| :--- | :--- |\n| `ArrayEqualityComparer` | Implements an equality comparer that is able to check two array for equality. The class is useful when using dictionaries/sets whose keys are arrays. |\n| `Temporary` | A class used to store a value for a specific amount of time. The value expires and has to be reloaded. **Multi-threaded** |\n| `BitWriter` | A specialized I/O class that implements the *Stream* base class. Allows for writing to a stream with bit granularity. |\n| `GlobPattern` | Simple class that allows checking if a string matches a glob-like pattern (e.g. _\"some*.?xt\"_) |\n| `DependencySquid` | Class that helps represent the state of a dependancy tree (including conflicts). Can be used to validate selection viability (think package dependancies). |\n| `Cached` | A simple wrapper that allows storing a value and considering it \"valid\" for a certain duration. Automatic value refresh is performed when value expires. |\n| `NanoCache` | A very simple cache container. Very useful when quick-and-dirty caching is needed. |\n\n### The list of implemented algorithms/helper methods:\n| Algorithm/Method | Description |\n| :--- | :--- |\n| `LinkedListNode.TryGetMiddleAndTailNodes` | Finds the middlem, tail nodes and the length of the list in one pass. If the list is circular, the method returns `-1` See related material: \u003chttps://en.wikibooks.org/wiki/Data_Structures/LinkedLists\u003e |\n| `LinkedListNode.Reverse` | *Reverses* a singly-linked list using the recursive algorithm. See related material: \u003chttps://en.wikibooks.org/wiki/Data_Structures/LinkedLists\u003e  |\n| `LinkedListNode.GetIntersectionNode` | Find the node that is the *intersection* of two singly-linked. See related material: \u003chttps://en.wikibooks.org/wiki/Data_Structures/LinkedLists\u003e  |\n| `LinkedListNode.GetKnotNode` | Find the node that connects the tail of the list to another interior node (knot) in a singly-linked. See related material: \u003chttps://www.geeksforgeeks.org/detect-and-remove-loop-in-a-linked-list/\u003e  |\n| `Graph.TraverseBfs` | Traverses the vertices in a graph using the *breadth-first search*. See related material: \u003chttps://en.wikipedia.org/wiki/Breadth-first_search\u003e |\n| `Graph.TraverseDfs` | Traverses the vertices in a graph using the *depth-first search*. See related material: \u003chttps://en.wikipedia.org/wiki/Depth-first_search\u003e |\n| `Graph.FillWithOneColor` | *Fills* all vertices of a graph with a given \"color\". See related material: \u003chttps://en.wikipedia.org/wiki/Flood_fill\u003e |\n| `Graph.FindShortestPath` | Find the *shortest path* between two graph vertices. See related material: \u003chttps://en.wikipedia.org/wiki/Shortest_path_problem\u003e  |\n| `Graph.GetComponents` | Finds all distinct *connected components* of a graph. The method returns each component represented as another graph. See related material: \u003chttps://en.wikipedia.org/wiki/Connected_component_(graph_theory)\u003e |\n| `Graph.TopologicalSort` | Implements the *topological sorting* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Topological_sorting\u003e |\n| `Graph.FindAllArticulationVertices` | Finds all *articulation points* in a graph. See related material: \u003chttps://en.wikipedia.org/wiki/Biconnected_component\u003e |\n| `Graph.IsBipartite` | Checks if a graph is *bipartite*. See related material: \u003chttps://en.wikipedia.org/wiki/Bipartite_graph\u003e |\n| `Graph.DescribeVertices` | Returns a *description* of all vertices in a graph, including in-degree, out-degree and component index. |\n| `Graph.FindCheapestPath` | Finds the *cheapest path* between two vertices in a graph. See related material: \u003chttps://en.wikipedia.org/wiki/A*_search_algorithm\u003e |\n| `Graph.Colorize` | Finds the minimum number of colors and applies thm on graph verticesh. See related material: \u003chttps://en.wikipedia.org/wiki/Graph_coloring\u003e |\n| `FibonacciSequence.Enumerate` | Lists all *Fibonacci numbers* up to a given index in the series. See related material: \u003chttps://en.wikipedia.org/wiki/Fibonacci_number\u003e |\n| `FibonacciSequence.GetMember` | Returns the *Fibonacci number* at a given index in the series. See related material: \u003chttps://en.wikipedia.org/wiki/Fibonacci_number\u003e |\n| `Integer.DeconstructIntoPowersOfTwo` | *Deconstructs* an integer into a sum of powers of two. |\n| `Integer.DeconstructIntoPrimeFactors` | *Deconstructs* an integer into a prime factors. |\n| `Integer.Break` | *Deconstructs* an integer into repeatable components. See related material: \u003chttps://en.wikipedia.org/wiki/Change-making_problem\u003e |\n| `Integer.IsPrime` | Checks whether an integer is a *prime number*. |\n| `Integer.Zip` | *Zips the digits* of two integers into a new integer. |\n| `Integer.Divide` | A simple *division* algorithm that only uses addition. |\n| `Integer.Swap` | Algorithm that performs a *swap* of two integers without an additional variable. |\n| `Integer. GetCountOfTrailingZeroesInFactorial` | Find the number of *trailing zeroes* for a factorial number. See related material: \u003chttps://www.geeksforgeeks.org/count-trailing-zeroes-factorial-number/\u003e |\n| `Integer.Max` | Returns the *maximum of two integers* without using comparisons. |\n| `Integer.Sum` | Returns the *sum of two integers* using only bitwise operations. |\n| `IntegerPartitions.Enumerate` | Enumerates all *integer partitions* for a given number. |\n| `IntegerPartitions.GetCount` | Calculates the number of *integer partitions* for a given number. |\n| `Knapsack.Fill` | The generic *0/1 knapsack* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Knapsack_problem\u003e |\n| `Interval.MergeOverlapping` | Merges a sequence of overlapping intervals (_or whatever intervals do overlap_) leaving the other ones untouched. |\n| `Interval.ChoseBestNonOverlapping` | Selects the non-overlapping (and scored) intervals that yeild the best aggregate score. |\n| `Pairing.GetPairsWithMinimumCost` | *Pairs the elements of a sequence* as to minimize the cost of each pair. |\n| `Pairing. GetPairsWithApproximateMinimumCost` | *Pairs the elements of a sequence* as to approximate minimization of the cost of each pair.  |\n| `Pairing.GetPairWithMaximumDifference` | Find the first pair in a sequence whose elements *yield the greatest difference*. |\n| `Pairing. GetPairWithIncreasingOrderMaximumDifference` | Find the first pair in a sequence whose elements *yield the greatest difference* with the restriction that elements in eth pair are strictly increasing. |\n| `Pairing.GetEqualizationPairs` | Finds all pairs of elements from both sequences whose values, if swapped, makes the sequences being equal in their sum. |\n| `ZArray.Construct` | Constructs a *Z-array* from a given input sequence. Z-arrays are useful for string pattern matching. See related materials: \u003chttp://wittawat.com/assets/talks/z_algorithm.pdf\u003e, \u003chttps://shiv4289.wordpress.com/2013/09/17/z-algorithm-for-pattern-matching/\u003e |\n| `RandomExtensions.Sample` | A *random sampling* algorithm for a sequence of objects. See related material: \u003chttps://en.wikipedia.org/wiki/Reservoir_sampling\u003e |\n| `RandomExtensions.NextBool` | An extension method that allows retrieving a *random boolean* value. |\n| `RandomExtensions.NextItem` | An extension method that allows retrieving a *random item* from a sequence of objects. |\n| `SequenceAlgorithms. FindLongestIncreasingSequence` | Finds the *longest increasing sequence* within a given sequence. |\n| `SequenceAlgorithms. ContainsTwoElementsThatAggregateTo` | Determines whether the sequence contains two elements *that aggregate to a given target*. |\n| `SequenceAlgorithms.FindDuplicates` | *Finds duplicates* in a sequence. A specialized and optimized version for integer sequences also provided. |\n| `SequenceAlgorithms.FindUniques` | *Finds unique* elements in a sequence. |\n| `SequenceAlgorithms.FindUniquesInOrder` | *Finds unique* elements in a sequence and retains the order of their appearance in the sequence. |\n| `SequenceAlgorithms.ExtractNestedBlocks` | An algorithm to allow *extracting nested* sub-sequences from a sequence (e.g. _\"(a(b))\"_ would return _\"(b)\"_ then _\"(a(b))\"_). |\n| `SequenceAlgorithms. GetSubsequencesOfAggregateValue` | Finds all *sub-sequences of a given aggregated value* in another sequence. |\n| `SequenceAlgorithms.Interleave` | Creates a sequence which combines multiple *interleaved sequences* based on a given comparison. |\n| `SequenceAlgorithms.Reverse` | *Reverses* a sequence in place. |\n| `SequenceAlgorithms.Repeat` | Creates a sequence which is based on the original sequence *repeated a number of times*. |\n| `SequenceAlgorithms.BinarySearch` | Implements the standard *binary search* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Binary_search_algorithm\u003e |\n| `SequenceAlgorithms.BinaryLookup` | Implements a slightly modified *binary search* algorithm that returns the range of matching items or the position of immediatelly smaller item. See related material: \u003chttps://en.wikipedia.org/wiki/Binary_search_algorithm\u003e |\n| `SequenceAlgorithms.Diff` | Implements the generic *edit distance* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Edit_distance\u003e |\n| `SequenceAlgorithms. GetLongestCommonSubSequence` | Finds the longest sub-sequence that is common to two distinct sequences. See related material: \u003chttps://en.wikipedia.org/wiki/Longest_common_subsequence_problem\u003e |\n| `SequenceAlgorithms.DeconstructIntoTerms` | Deconstructs a given sequence into a sequence of terms (sub-sequences) based on given term scoring (e.g. think of recognizing an English phrase for all lower-case text without whitespaces using a given dictionary of known words: \"_ilovecookies_\" will be split into \"_i_\", \"_love_\", \"_cookies_\"). |\n| `SequenceAlgorithms.GetItemFrequencies` | Gets the *items and their frequencies* within a sequence. |\n| `SequenceAlgorithms.IsPalindrome` | Checks if a given (sub)sequence is a palindrome. See related material: \u003chttps://en.wikipedia.org/wiki/Palindrome\u003e |\n| `SequenceAlgorithms. IsPermutationOfPalindrome` | Checks if a given (sub)sequence is a possible permutation of palindrome. See related material: \u003chttps://en.wikipedia.org/wiki/Palindrome\u003e |\n| `SequenceAlgorithms.IndexOfPermutationOf` | Finds the first occurence of sub-sequence (or any of its permutations) in the given sequence. |\n| `SequenceAlgorithms. FindUnorderedSubsequenceRange` | Finds the *un-ordered sub-sequence* inside a given sequence. Once found sub-sequence is sorted, the whole sequence becomes ordered. |\n| `SequenceAlgorithms. GetRangeWithGreatestAggregateValue` | Finds the sub-sequence range with the *greatest aggregate* value. |\n| `SequenceExtensions.ToSet` | Helper methods to *convert a given sequence into a set*. |\n| `SequenceExtensions.AsList` | Helper method that *interprets a given sequence as a list*. If the sequence is already a list/array then the original object is returned; otherwise, the sequence is converted to an array. **This method may or may not create a new object and does not guarantee mutability of the result.** |\n| `SequenceExtensions.Copy` | Helper method to *copy a sub-sequence* into a new array. |\n| `SequenceExtensions.AddOrUpdate` | Extends the dictionary classes with the ability to *add a new, or update an existing* key/pair. |\n| `SequenceExtensions.Increment` | Extends the dictionary classes with the ability to *increment integer value* for a given key (treating non-existing keys as having value of zero). |\n| `SequenceExtensions.Append` | A number of small utility methods used to *append items to arrays*. If the array is null, a new array is created. These methods return new arrays as their return values. |\n| `SequenceExtensions.ToList` | Utility method that replaces a common _\"Select(...).Tolist()\"_ LINQ pattern. |\n| `SequenceExtensions.Partition` | *Partitions* a given sequence into a batch of smaller partitions of a given size. |\n| `SequenceExtensions.EmptyIfNull` | Method returns an *empty sequence* if the current sequence is null; otherwise it returns the sequence itself. |\n| `SequenceExtensions.IsNullOrEmpty` | Mimics the **String.IsNullOrEmpty** method. |\n| `SequenceExtensions.ToString` | Utility method that replaces a common _\"String.Join(..., ...Select(...))\"_ LINQ pattern. |\n| `SequenceExtensions.Min` | Returns the element of a sequence with a given *selected minimum* (e.g. select the person object with the smallest age). |\n| `SequenceExtensions.Max` | Returns the element of a sequence with a given *selected maximum* (e.g. select the person object with the greatest age). |\n| `SequenceExtensions.Segment` | Returns a view of the original sequence bounded to a segment of the list. Useful when other methods do not allow specifying a start/length pair of arguments. |\n| `SequenceExtensions.SelectValues` | Selects the *values of a sequence of nullables*. Nullable items that have no value are skipped. |\n| `SequenceExtensions.Separate` | Separates items from a sequence into *two distinct arrays* based on a predicate. |\n| `SequenceExtensions.Unzip` | Splits tuples (and key-value pairs) into separate array containing individual items. |\n| `SequenceExtensions.IsValidAdjacency` | Checkes whether all sequence adjacent elements satisfy a common condition. |\n| `SequenceExtensions.IsOrdered` | Checkes whether the elements of a given sequence are sorted in ascending order. |\n| `SequenceExtensions.IsStrictlyOrdered` | Checkes whether the elements of a given sequence are strictly sorted in ascending order. |\n| `SequenceExtensions.IsOrderedDescending` | Checkes whether the elements of a given sequence are sorted in descending order. |\n| `SequenceExtensions. IsStrictlyOrderedDescending` | Checkes whether the elements of a given sequence are strictly sorted in descending order. |\n| `SequenceExtensions.Fold` | *Folds a sequence* by merging consecutive appearances of a given item into one output item (think reduce). |\n| `Set.EnumerateSubsetCombinations` | *Splits a set into subsets* of a given length and returns all such combinations. |\n| `Set.SplitIntoSubsetsOfEqualValue` | Tries to find all *subsets with equal aggregate value*. See related material: \u003chttp://www.usaco.org/index.php?page=viewproblem2\u0026cpid=139\u003e |\n| `Set.GetSubsetWithNearValue` | Extracts a subset of integers whose sum is equal or very *close to the target value*. |\n| `Set.ContainsSubsetWithExactValue` | Checks whether there is a subset of integers whose sum is *equal to a target value*. |\n| `Set.GetSubsetWithGreatestValue` | Finds the first *N* number of pairs with greatest sums. |\n| `Set.GetPermutations` | Evaluates and returns all permutations of a given set. See related material: \u003chttps://en.wikipedia.org/wiki/Permutation\u003e |\n| `Sorting.BubbleSort` | Implements the standard *bubble sort* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Bubble_sort\u003e |\n| `Sorting.CocktailShakerSort` | Implements the standard *cocktail shaker sort* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Cocktail_shaker_sort\u003e |\n| `Sorting.CombSort` | Implements the standard *comb sort* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Comb_sort\u003e |\n| `Sorting.GnomeSort` | Implements the standard *gnome sort* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Gnome_sort\u003e |\n| `Sorting.HeapSort` | Implements the standard *heapsort* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Heapsort\u003e |\n| `Sorting.InsertionSort` | Implements the standard *insertion sort* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Insertion_sort\u003e |\n| `Sorting.MergeSort` | Implements the standard *merge sort* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Merge_sort\u003e |\n| `Sorting.OddEvenSort` | Implements the standard *odd-even sort* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Odd%E2%80%93even_sort\u003e |\n| `Sorting.QuickSort` | Implements the standard *quicksort* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Quicksort\u003e |\n| `Sorting.ShellSort` | Implements the standard *shellsort* algorithm. See related material: \u003chttps://en.wikipedia.org/wiki/Shellsort\u003e |\n| `ObjectExtensions.IsAnyOf` | Helper methods that allows checking if an object is *equal to any other object* in a sequence (think of *_x IN (o1, o2, o3)*). |\n| `ObjectExtensions.Inspect` | A simple helper method that allows *extracting fields/properties/methods* values from an object as a dictionary. |\n| `ObjectExtensions.TryConvert` | Tries to *convert* a given object to a given type. Uses different techniques to achieve this goal. |\n| `ObjectExtensions.As` | A simpler version of *TryConvert* that throws an exception if the conversion is not possible. |\n| `StringExtensions.AsList` | Returns a *wrapper IList\u0026lt;char\u0026gt;* object. Useful when using other algorithms that expect a list. **The returned list is read-only for obvious reasons.** |\n| `StringExtensions.Reverse` | *Reverses* a string and returns the reversed version. |\n| `StringExtensions.Shorten` | *Shortens* a string to a given maximum length (considering Unicode surrogate-pairs, etc.). Allows for an optional \"shortening indicator string\" used at the end of the string (think *\"This is a go...\"*).  |\n| `StringExtensions.Escape` | Escapes a string using the standard \"C\" escape sequences (e.g. _\"\\n\"_ for new line). |\n| `StringExtensions.Like` | A wrapper method on top of **GlobPattern** class. A convenient method to check if a *string matches a pattern*.  |\n| `StringExtensions.FindDuplicates` | Finds *duplicate characters* in the string. Uses both a set and a small array for ASCII characters. |\n| `StringExtensions.SplitIntoLines` | *Splits* a given string into its contituent lines. Treats both _\"\\n\"_ and _\"\\r\\n\"_ as line breaks. |\n| `StringExtensions.WordWrap` | *Word-wraps* a string to a given max line length. Uses white-spaces and puctuation characters as potential line breaks. |\n| `StringExtensions.StripDiacritics` | *Strips the Unicode diacritics* from a text. Useful for text normalization in searches. |\n| `StringBuilderExtensions. AppendNotEmptyLine` | *Appends a line to the string builder* if the line is not empty. |","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavkam%2Fabacaxi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpavkam%2Fabacaxi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpavkam%2Fabacaxi/lists"}