The json-pointer draft is missing a very important piece: slices.
var obj = {
foo: [
{ bar: 1 },
{ bar: 2 },
{ bar: 3 }
]
};
You can only drill down into an array with a specific index.
- pointer
/foo/1/bar
- value
2
- javascript equivalent
foo[1].bar
With a slice you can grab a range of values.
- pointer
/foo/1:3/bar
- value
[2, 3]
- javascript equivalent
foo.slice(1, 3).map(function (obj) { return obj.bar; });
The json-pointer draft is used by the json-patch. Without slices, you are restricted to treating arrays like pojo's.
Say for example you wanted to write a patch that removes
100 elements from an array.
Currently you have to write 100 separate remove
operations with each one specifying the index.
I think we can do better.
Edit: Here's a better one
Here is a naive implementation. demo
var getPointedValue = function (pointer, obj) {
if (pointer.length === 0)
return obj;
var sepIndex = pointer.indexOf('/');
if (sepIndex === 0)
return getPointedValue(pointer.substr(1), obj);
if (sepIndex === -1)
sepIndex = pointer.length;
var firstPart = pointer.substr(0, sepIndex),
restParts = pointer.substr(sepIndex + 1),
colIndex = firstPart.indexOf(':');
if (colIndex === -1)
return getPointedValue(restParts, obj[firstPart]);
var sliceStart = parseInt(firstPart.substr(0, colIndex), 10),
sliceEnd = parseInt(firstPart.substr(colIndex + 1), 10);
if (isNaN(sliceStart) || !isFinite(sliceStart)) sliceStart = 0;
if (isNaN(sliceEnd) || !isFinite(sliceEnd)) sliceEnd = 0;
return obj.slice(sliceStart, sliceEnd).map(function (obj) {
return getPointedValue(restParts, obj);
});
};
Object.prototype.pointer = function (p) { return getPointedValue(p, this); }
Example Usage:
var pointers = [
'/foo/0:1',
'/foo/0:2',
'/foo/0:1/bar',
'/foo/1:2/bar'
];
pointers.forEach(function (p) {
var val = obj.pointer(p);
console.log([
p, "=>", JSON.stringify(val)
].join(" "));
});