Knockout.JS: AsDictionary

http://www.wiredprairie.us/blog/index.php/archives/1563

HTML

<ul data-bind="foreach: items">
    <li>
        <span data-bind="text: name"></span>
        <a href="#" data-bind="click: $root.items.remove.bind($root.items)"> x </a>
    </li>
</ul>

<button data-bind="click: addItem">Add Item</button>
    
<hr/>
<input data-bind="value: searchText" />
<div data-bind="text: searchResult().name"></div>

CSS

td { padding: 2px; }

JavaScript

ko.observableArray.fn.indexBy = function (keyName) {
    var index = ko.computed(function () {
        var list = this() || [];
        var keys = {}; 
        ko.utils.arrayForEach(list, function (v) {
            if (keyName) {          
                keys[v[keyName]] = v;   
            } else {
                keys[v] = v;
            }
        });
        return keys;
    }, this);
    
    this.findByKey = function(key) {
        return index()[key];  
    };
    
    return this;
};

var ViewModel = function () {
    var count = 0;
    
    this.items = ko.observableArray([]).indexBy("id");
    
    this.addItem = function() {
        this.items.push({
            id: ++count,
            name: ko.observable("item " + count)
        });   
    };
    
    this.removeItem = function(item) {
        this.items.remove(item);   
    }.bind(this);
    
    this.searchText = ko.observable(2);
    this.searchResult = ko.computed(function() {
        return this.items.findByKey(this.searchText()) || {};
    }, this);
};

ko.applyBindings(new ViewModel());