Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: CI

env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:

jobs:
build:
strategy:
matrix:
os: [macos-latest, ubuntu-latest, windows-latest]
smalltalk: [Pharo64-13, Pharo64-12, Pharo64-11, Pharo64-10]

runs-on: ${{ matrix.os }}
name: ${{ matrix.smalltalk }} on ${{ matrix.os }}

steps:
- uses: actions/checkout@v3
- name: Setup SmalltalkCI
uses: hpi-swa/setup-smalltalkCI@v1
with:
smalltalk-version: ${{ matrix.smalltalk }}
- name: Load and Test
run: smalltalkci -s ${{ matrix.smalltalk }}
shell: bash
timeout-minutes: 15
31 changes: 0 additions & 31 deletions .github/workflows/matrix.yml

This file was deleted.

40 changes: 0 additions & 40 deletions .travis.yml

This file was deleted.

97 changes: 79 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
# Containers-OrderedSet

[![Build Status](https://travis-ci.org/olekscode/Containers-OrderedSet.svg?branch=master)](https://travis-ci.org/olekscode/Containers-OrderedSet)
[![Build status](https://ci.appveyor.com/api/projects/status/te7uf184lua3svb4?svg=true)](https://ci.appveyor.com/project/olekscode/containers-orderedset)
[![Coverage Status](https://coveralls.io/repos/github/olekscode/Containers-OrderedSet/badge.svg?branch=master)](https://coveralls.io/github/olekscode/Containers-OrderedSet?branch=master)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/olekscode/Containers-OrderedSet/master/LICENSE)
[![Pharo version](https://img.shields.io/badge/Pharo-6.1-%23aac9ff.svg)](https://pharo.org/download)
[![Pharo version](https://img.shields.io/badge/Pharo-7.0-%23aac9ff.svg)](https://pharo.org/download)
[![Pharo version](https://img.shields.io/badge/Pharo-8.0-%23aac9ff.svg)](https://pharo.org/download)
![Pharo Version](https://img.shields.io/badge/Pharo-10+-blue)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)

A `Set` where an order of elements matters or an `OrderedCollection` with no duplicates. Supports the complete API of `Set` and `OrderedCollection`.
A `CTOrderedSet` is a collection that combines the properties of a `Set` and an `OrderedCollection`. It maintains the order of elements while ensuring that there are no duplicates, similar to a `Set`. This makes it a useful data structure when you need to keep track of the order in which items were added, while also enforcing uniqueness.

### Key Features
- **Maintains Insertion Order**: Elements are stored in the order they were added.
- **Ensures Uniqueness**: No duplicate elements are allowed.
- **Indexed Access**: Elements can be accessed by their index, similar to an array.
- **Rich API**: Combines methods from both `Set` and `OrderedCollection`, allowing for flexible usage.
- **Developer Productivity**: Simplifies code by eliminating the need for manual duplicate checks and order management.

## Installation
To install `CTOrderedSet`, go to the Playground (`Ctrl+OW`) in your [Pharo](https://pharo.org/) image and execute the following Metacello script (select it and press Do-it button or `Ctrl+D`):
To install `CTOrderedSet`, go to the Playground in your [Pharo](https://pharo.org/) image and execute the following Metacello script (select it and press Do-it button or `Ctrl+D`):

```Smalltalk
Metacello new
Expand All @@ -33,18 +35,77 @@ spec
To read more about baselines and Metacello, check out the [Baselines](https://github.com/pharo-open-documentation/pharo-wiki/blob/master/General/Baselines.md) article on [Pharo Wiki](https://github.com/pharo-open-documentation/pharo-wiki).

## How to use it?
You can create an `OrderedSet` and use it like this:
```smalltalk
| orderedSet |
orderedSet := CTOrderedSet new.
orderedSet add: 'Apple'.
orderedSet add: 'Banana'.
orderedSet add: 'Apple'. "This will not add a duplicate"
orderedSet add: 'Cherry'.
orderedSet do: [ :each | Transcript show: each; cr ].
```
This will output:
```
Apple
Banana
Cherry
```

`CTOrderedSet` has the same API as `OrderedCollection`, extended with the methods of `Set`. So instance creation looks the same:
### Real World Use Case: Blog Tag Management
Let's explore a comprehensive example that demonstrates the power of `OrderedSet` in a real-world scenario - managing tags for a blog post. This example illustrates how to maintain order, ensure uniqueness, and perform efficient operations on tags.

```Smalltalk
firstBasket := CTOrderedSet withAll: #(apple apple orange banana orange banana).
secondBasket := CTOrderedSet withAll: #(banana apple banana banana).
```
```smalltalk
"Blog post tag management - Maintain order, Ensure uniqueness"

Or you can use the `asOrderedSet` method:
"Traditional approach with OrderedCollection - problematic"
blogTags := OrderedCollection new.
blogTags
add: 'Programming';
add: 'Pharo';
add: 'Tutorial';
add: 'Programming'; "Oops! Duplicate"
add: 'Beginner';
add: 'Pharo'. "Another duplicate"
"Manual cleanup required - inefficient and error-prone"
blogTags := blogTags asSet asOrderedCollection. "Loses order!"
"Result: Unpredictable order, Manual management needed"

```Smalltalk
firstBasket := #(apple apple orange banana orange banana) asOrderedSet.
secondBasket := #(banana apple banana banana) asOrderedSet.
"OrderedSet approach - Elegant and Automatic"
blogTags := CTOrderedSet new.
blogTags
add: 'Programming';
add: 'Pharo';
add: 'Tutorial';
add: 'Programming'; "Automatically ignored - No duplicate"
add: 'Beginner';
add: 'Pharo'. "Automatically ignored - No duplicate"

"Result: #('Programming' 'Pharo' 'Tutorial' 'Beginner') - Perfect order, No duplicates"

"Adding tags from user input or external sources"
userInputTags := #('Advanced' 'Programming' 'Smalltalk' 'Tutorial').
blogTags addAll: userInputTags.
"Result: #('Programming' 'Pharo' 'Tutorial' 'Beginner' 'Advanced' 'Smalltalk') - Maintains order, no duplicates"
"Notice: Duplicates automatically filtered, new tags appended in order"

blogTags includes: 'Pharo'. "Returns: True"
blogTags includes: 'JavaScript'. "Returns: False"

firstTag := blogTags first. "Access first tag - 'Programming'"
lastTag := blogTags last. "Access last tag - 'Smalltalk'"
thirdTag := blogTags at: 3. "Access third tag - 'Tutorial'"
```

### Comparison with Alternatives

| Feature | OrderedCollection | Set | CTOrderedSet |
|---------|------------------|-----|-------------|
| Maintains order | Yes | No | Yes |
| Prevents duplicates | No | Yes | Yes |
| Indexed access | Yes | No | Yes |
| Manual Duplicate Check | Required | Not Required | Not Required |

## Contributing

This is part of the Pharo Containers project. Feel free to contribute by implementing additional methods, improving tests, or enhancing documentation.
29 changes: 0 additions & 29 deletions appveyor.yml

This file was deleted.

Loading