Giter Site home page Giter Site logo

indexedstorage's Introduction

IndexedStorage

Swift License Build Status

A wrapper around Swifts Dictionary type that creates and maintains multiple indices for stored Structs. You should not use it with mutable classes, because IndexedStorage will not observe properties of class instances to keep the indices up-to-date.

Install

This library should be installable via SwiftPM, Carthage and CocoaPods.

Example

Let's say you have a struct that looks like this:

struct Ship {
    let id: String
    let name: String
    let captain: String
}

1. Define Your Data Storage Subclass

To create a storage class by subclassing you need to define the Element type (Ship) and the type of the PrimaryKey you wish to use to store your data. In this case String, because we want ship.id to be the primary key. This key should be unique and Hashable.

class ShipData: IndexedStorage<Ship, String> {
}

2. Override Index Function

Our goal is to use ship.id as key for the primary index. Next, we want to maintain two additional indices for ship.name and ship.captain.

To achieve that, we need to override three functions:

2.1. Primary Key Access For The Primary Index

override class func primaryKey(for element: Ship) -> String {
    return element.id
}

2.2. Number Of Additional Indices

"2" for ship.name and ship.captain.

override class func numberOfIndices() -> Int {
    return 2
}

2.3. Hashes For The Additional Indices

By returning hashes for ship.name and ship.captain we provide all the information needed to build the additional indices. Make sure the array length equals the number returned by numberOfIndices. Otherwise the class will crash.

override class func hashValues(for element: Ship) -> [Int] {
    return [element.name.hashValue, element.captain.hashValue]
}

3. Create Convenience Accessors

You can now access structs using the additional indices by calling indexedStorage.elements(for: name, onIndex: 0). But it is more convenient to provide custom subscript functions like:

subscript(name name: String) -> [Ship] {
    return elements(for: name, onIndex: 0)
}

subscript(captain captain: String) -> [Ship] {
    return elements(for: captain, onIndex: 1)
}

4. The Final Class

class ShipData: IndexedStorage<Ship, String> {

    override class func primaryKey(for element: Ship) -> String {
        return element.id
    }

    override class func numberOfIndices() -> Int {
        return 2
    }

    override class func hashValues(for element: Ship) -> [Int] {
        return [element.name.hashValue, element.captain.hashValue]
    }

    subscript(name name: String) -> [Ship] {
        return elements(for: name, onIndex: 0)
    }

    subscript(captain captain: String) -> [Ship] {
        return elements(for: captain, onIndex: 1)
    }
}

Usage

You can now access like this:

// Add
let enterprisePike = Ship(id: "USS-1701", name: "Enterprise", captain: "Christopher Pike")
shipData.add(enterprisePike)

let enterpriseD = Ship(id: "USS-1701-D", name: "Enterprise", captain: "Jean-Luc Picard")
shipData.add(enterpriseD)

// Update
let enterpriseKirk = Ship(id: "USS-1701", name: "Enterprise", captain: "James T. Kirk")
shipData.add(enterpriseKirk) // `enterprisePike` will be replaced because of the same `id`.

// Access
shipData["USS-1701"]
// => Ship(id: "USS-1701", name: "Enterprise", captain: "James T. Kirk")

shipData[name: "Enterprise"]
// => [Ship(id: "USS-1701", name: "Enterprise", captain: "James T. Kirk"), Ship(id: "USS-1701-D", name: "Enterprise", captain: "Jean-Luc Picard")]

shipData[captain: "James T. Kirk"]
// => [Ship(id: "USS-1701", name: "Enterprise", captain: "James T. Kirk")]

// Remove
shipData.remove(enterprise)

// Remove By Primary Key
shipData.remove(key: "USS-1701")

License

This project is released under the MIT license. See LICENSE for details.

indexedstorage's People

Contributors

uberbruns avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.