Skip to content

toggle

Toggle the existence state of an element in an array. If the element exists, remove it; if it doesn't exist, add it.

Basic Usage

typescript
import { toggle } from 'radash'

const fruits = ['apple', 'banana', 'cherry']

const updated = toggle(fruits, 'banana')
// ['apple', 'cherry'] (banana removed)

const updated2 = toggle(fruits, 'orange')
// ['apple', 'banana', 'cherry', 'orange'] (orange added)

Syntax

typescript
function toggle<T>(
  array: readonly T[],
  item: T
): T[]

Parameters

  • array (readonly T[]): The array to operate on
  • item (T): The element to toggle

Return Value

Returns a new array containing the toggled elements.

Examples

Basic Toggle

typescript
import { toggle } from 'radash'

const tags = ['javascript', 'react', 'typescript']

// Remove existing element
const withoutReact = toggle(tags, 'react')
// ['javascript', 'typescript']

// Add non-existing element
const withVue = toggle(tags, 'vue')
// ['javascript', 'react', 'typescript', 'vue']

Toggle Numbers

typescript
import { toggle } from 'radash'

const numbers = [1, 2, 3, 4, 5]

const withoutThree = toggle(numbers, 3)
// [1, 2, 4, 5]

const withSix = toggle(numbers, 6)
// [1, 2, 3, 4, 5, 6]

Toggle Objects

typescript
import { toggle } from 'radash'

const users = [
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' }
]

const userToToggle = { id: 2, name: 'Bob' }

const updated = toggle(users, userToToggle)
// [{ id: 1, name: 'Alice' }] (Bob removed)

const newUser = { id: 3, name: 'Charlie' }
const withNewUser = toggle(users, newUser)
// [
//   { id: 1, name: 'Alice' },
//   { id: 2, name: 'Bob' },
//   { id: 3, name: 'Charlie' }
// ]

Toggle Boolean Values

typescript
import { toggle } from 'radash'

const flags = [true, false, true]

const withoutTrue = toggle(flags, true)
// [false, true] (first true removed)

const withFalse = toggle(flags, false)
// [true, false, true, false] (false added)

Using in State Management

typescript
import { toggle } from 'radash'

interface Todo {
  id: number
  text: string
  completed: boolean
}

class TodoManager {
  private todos: Todo[] = []

  toggleTodo(todoId: number) {
    const todo = this.todos.find(t => t.id === todoId)
    if (todo) {
      this.todos = toggle(this.todos, todo)
    }
  }

  addTodo(text: string) {
    const newTodo: Todo = {
      id: Date.now(),
      text,
      completed: false
    }
    this.todos = toggle(this.todos, newTodo)
  }

  getTodos() {
    return this.todos
  }
}

const manager = new TodoManager()
manager.addTodo('Learn React')
manager.addTodo('Build app')
manager.toggleTodo(manager.getTodos()[0].id) // Remove first todo

Handle Tag System

typescript
import { toggle } from 'radash'

class TagManager {
  private selectedTags: string[] = []

  toggleTag(tag: string) {
    this.selectedTags = toggle(this.selectedTags, tag)
  }

  getSelectedTags() {
    return this.selectedTags
  }

  hasTag(tag: string) {
    return this.selectedTags.includes(tag)
  }
}

const tagManager = new TagManager()
tagManager.toggleTag('javascript')
tagManager.toggleTag('react')
tagManager.toggleTag('javascript') // Remove javascript

console.log(tagManager.getSelectedTags()) // ['react']

Handle Permission System

typescript
import { toggle } from 'radash'

interface Permission {
  id: string
  name: string
  description: string
}

class PermissionManager {
  private userPermissions: Permission[] = []

  togglePermission(permission: Permission) {
    this.userPermissions = toggle(this.userPermissions, permission)
  }

  hasPermission(permissionId: string): boolean {
    return this.userPermissions.some(p => p.id === permissionId)
  }

  getPermissions() {
    return this.userPermissions
  }
}

const permissionManager = new PermissionManager()
const readPermission: Permission = { id: 'read', name: 'Read', description: 'Read access' }
const writePermission: Permission = { id: 'write', name: 'Write', description: 'Write access' }

permissionManager.togglePermission(readPermission)
permissionManager.togglePermission(writePermission)
permissionManager.togglePermission(readPermission) // Remove read permission

console.log(permissionManager.getPermissions()) // [writePermission]

Handle Bookmark Feature

typescript
import { toggle } from 'radash'

interface Bookmark {
  id: string
  url: string
  title: string
  timestamp: number
}

class BookmarkManager {
  private bookmarks: Bookmark[] = []

  toggleBookmark(bookmark: Bookmark) {
    this.bookmarks = toggle(this.bookmarks, bookmark)
  }

  isBookmarked(url: string): boolean {
    return this.bookmarks.some(b => b.url === url)
  }

  getBookmarks() {
    return this.bookmarks
  }
}

const bookmarkManager = new BookmarkManager()
const bookmark: Bookmark = {
  id: '1',
  url: 'https://example.com',
  title: 'Example',
  timestamp: Date.now()
}

bookmarkManager.toggleBookmark(bookmark) // Add bookmark
bookmarkManager.toggleBookmark(bookmark) // Remove bookmark

Handle Shopping Cart

typescript
import { toggle } from 'radash'

interface CartItem {
  id: string
  name: string
  price: number
  quantity: number
}

class ShoppingCart {
  private items: CartItem[] = []

  toggleItem(item: CartItem) {
    this.items = toggle(this.items, item)
  }

  getItems() {
    return this.items
  }

  getTotal() {
    return this.items.reduce((sum, item) => sum + (item.price * item.quantity), 0)
  }
}

const cart = new ShoppingCart()
const laptop: CartItem = { id: '1', name: 'Laptop', price: 999, quantity: 1 }
const phone: CartItem = { id: '2', name: 'Phone', price: 599, quantity: 1 }

cart.toggleItem(laptop) // Add laptop
cart.toggleItem(phone)  // Add phone
cart.toggleItem(laptop) // Remove laptop

console.log(cart.getItems()) // [phone]
console.log(cart.getTotal()) // 599

Handle Filters

typescript
import { toggle } from 'radash'

class FilterManager {
  private activeFilters: string[] = []

  toggleFilter(filter: string) {
    this.activeFilters = toggle(this.activeFilters, filter)
  }

  isFilterActive(filter: string): boolean {
    return this.activeFilters.includes(filter)
  }

  getActiveFilters() {
    return this.activeFilters
  }

  clearFilters() {
    this.activeFilters = []
  }
}

const filterManager = new FilterManager()
filterManager.toggleFilter('category:electronics')
filterManager.toggleFilter('price:under-100')
filterManager.toggleFilter('category:electronics') // Remove electronics category

console.log(filterManager.getActiveFilters()) // ['price:under-100']

Handle Multi-select List

typescript
import { toggle } from 'radash'

class MultiSelectList {
  private selectedItems: any[] = []

  toggleItem(item: any) {
    this.selectedItems = toggle(this.selectedItems, item)
  }

  getSelectedItems() {
    return this.selectedItems
  }

  isSelected(item: any): boolean {
    return this.selectedItems.includes(item)
  }

  selectAll(items: any[]) {
    this.selectedItems = [...items]
  }

  clearSelection() {
    this.selectedItems = []
  }
}

const multiSelect = new MultiSelectList()
const options = ['Option 1', 'Option 2', 'Option 3', 'Option 4']

multiSelect.toggleItem('Option 1')
multiSelect.toggleItem('Option 2')
multiSelect.toggleItem('Option 1') // Deselect Option 1

console.log(multiSelect.getSelectedItems()) // ['Option 2']

Notes

  1. Keep original array unchanged: toggle does not modify the original array, but returns a new array
  2. Reference comparison: Uses strict equality (===) to compare elements
  3. Object comparison: For objects, the same reference is needed to remove
  4. Performance: Time complexity is O(n), where n is the array length
  5. Duplicate elements: If there are multiple identical elements, only the first one is removed

Differences from Other Methods

  • push() + filter(): Requires manually checking if element exists
  • toggle(): Concise toggle method provided by radash
  • includes() + conditional operations: Requires more code to achieve the same functionality

Practical Application Scenarios

  1. Tag systems: Add/remove tags
  2. Permission management: Grant/revoke permissions
  3. Bookmark features: Add/remove bookmarks
  4. Shopping carts: Add/remove items
  5. Multi-select lists: Select/deselect items

Released under the MIT License.