Implement Set.At and Map.At in Go (#2903)

These get the set/map element at a specific index.
I haven't implemented it in JS yet because the JS code has no method to
create a cursor at an index. This exists in Go because a refactor was
done a few months ago to add it, but it hasn't been ported to JS.
This commit is contained in:
Ben Kalman
2016-12-04 11:27:35 -08:00
committed by GitHub
parent 87958507b0
commit 0a10704149
4 changed files with 53 additions and 0 deletions

View File

@@ -5,6 +5,7 @@
package types
import (
"fmt"
"sort"
"github.com/attic-labs/noms/go/d"
@@ -140,6 +141,16 @@ func (m Map) Last() (Value, Value) {
return m.firstOrLast(true)
}
func (m Map) At(idx uint64) (key, value Value) {
if idx >= m.Len() {
panic(fmt.Errorf("Out of bounds: %s >= %s", idx, m.Len()))
}
cur := newCursorAtIndex(m.seq, idx)
entry := cur.current().(mapEntry)
return entry.key, entry.value
}
func (m Map) MaybeGet(key Value) (v Value, ok bool) {
cur := newCursorAtValue(m.seq, key, false, false)
if !cur.valid() {

View File

@@ -1254,3 +1254,20 @@ func TestMapIterFrom(t *testing.T) {
assert.True(kvs[0:0].Equals(test(m1, Number(100), Number(1000))))
assert.True(kvs[50:60].Equals(test(m1, Number(0), Number(8))))
}
func TestMapAt(t *testing.T) {
assert := assert.New(t)
values := []Value{Bool(false), Number(42), String('a'), String('b'), String('c'), String('d')}
m := NewMap(values...)
for i := 0; i < len(values); i += 2 {
k, v := m.At(uint64(i / 2))
assert.Equal(values[i], k)
assert.Equal(values[i+1], v)
}
assert.Panics(func() {
m.At(42)
})
}

View File

@@ -5,6 +5,7 @@
package types
import (
"fmt"
"sort"
"github.com/attic-labs/noms/go/hash"
@@ -114,6 +115,15 @@ func (s Set) First() Value {
return cur.current().(Value)
}
func (s Set) At(idx uint64) Value {
if idx >= s.Len() {
panic(fmt.Errorf("Out of bounds: %s >= %s", idx, s.Len()))
}
cur := newCursorAtIndex(s.seq, idx)
return cur.current().(Value)
}
func (s Set) Insert(values ...Value) Set {
if len(values) == 0 {
return s

View File

@@ -986,3 +986,18 @@ func TestSetRemoveLastWhenNotLoaded(t *testing.T) {
assert.True(ts.toSet().Equals(ns))
}
}
func TestSetAt(t *testing.T) {
assert := assert.New(t)
values := []Value{Bool(false), Number(42), String('a'), String('b'), String('c')}
s := NewSet(values...)
for i, v := range values {
assert.Equal(v, s.At(uint64(i)))
}
assert.Panics(func() {
s.At(42)
})
}