Skip to content

Indexed based array is too limited #12

Open

Description

@jsumners

Given the documents:

{
  "version": 0,
  "roles": [
    { "name": "foo", "value": "bar" },
    { "name": "baz", "value": "foobar" },
    { "name": "fjsl", "value": "dowfo" }
  ]
}

And:

{
  "version": 1,
  "roles": [
    { "name": "foo", "value": "bar" },
    { "name": "fjsl", "value": "dowfo" }
  ]
}

I want to be able to write a patch:

{ "op": "remove", "path": "/roles/name", "value": "foobar" }

This is useful when there is no guarantee that the array will always be in the same order, despite being guaranteed to have the same elements.

As JSON Patch currently works, I'm just going to re-factor my array into a hash. But it'd be nice to have this ability in the future.

Activity

  1. grahamegrieve commented on Jan 31, 2016

    @grahamegrieve

    +1 for this. This restriction makes JSON Patch simple to implement, but also restricts it to very simple cases. A more sophisticated JSON patch that allowed you to specify a selection criteria for remove and replace (particularly) would allow JSON Patch to be used for a more robust set of use cases, but would significantly increase the complexity. Also, to my knowledge, there's no candidate query for json with a standards track?

  2. heruan commented on Nov 2, 2016

    @heruan

    I agree, remove operation should permit to remove array elements without knowing the index. For example, given this JSON:

    {
        "items": [ "a", "b", "c" ]
    }

    this patch should remove an item by value:

    { "op": "remove", "path": "/items/-", "value": "b" }

    to result in:

    {
        "items": [ "a", "c" ]
    }

    See #18.

  3. konrad7d commented on Feb 24, 2017

    @konrad7d

    +1. The ability to update or remove an element based on its property or wider selection criteria could be very useful.

  4. aalquist-akamai commented on Mar 2, 2017

    @aalquist-akamai

    +1. this would make my logic more simple. For now, I'm using the test operator as a safety check.

  5. HappyNomad commented on Sep 8, 2017

    @HappyNomad

    While navigating to the removal location, you may need to traverse more than one collection from which you need to select an element based on its property's value. The syntax proposed by @jsumners won't work in this more general case, since it splits the selection criteria into value of which there's only one.

    Expressing each such traversal in the path as property=value is possible but unnecessarily complex.
    A simpler approach is to assume the identifying property's name and say that property's value where we'd otherwise say the element's index in the array. This involves eliminating array indices from the spec, or at least introducing an alternative "entity mode". Instead of array indices, we'd use the value of an element's "id" (not case-sensitive) property. For collections of scalar values, it would instead be the value itself.

    So in @jsumners's simple example, the identifying property would be named "id" instead of "name". And the remove operation would be:

    { "op": "remove", "path": "/roles/foobar" }
    

    @heruan Your proposal only addresses collections of scalar values. What about collections of complex types as in @jsumners's example?

  6. mitar commented on Oct 12, 2019

    @mitar

    As I wrote in this comment:

    I feel this is going in the wrong direction and will make JSON patch be more and more like a programming language. I prefer to see JSON patch as a diff between known versions of JSON. Not a "program" to apply to unknown versions of JSON. The latter would then require more and more complicated logic. And how do we decide where it ends? Do you also want to define a function which computes the index at which to insert something? Or use regular expressions?

  7. xanscale commented on Feb 6, 2025

    @xanscale

    changing ARRAY to MAP<KEY, OBJECT> JSONPatch works by id and all works perfectly

  8. jsumners commented on Feb 6, 2025

    @jsumners
    Author

    changing ARRAY to MAP<KEY, OBJECT> JSONPatch works by id and all works perfectly

    ...

    As JSON Patch currently works, I'm just going to re-factor my array into a hash.

    Noted in the original post 10 years ago.

  9. xanscale commented on Feb 6, 2025

    @xanscale

    yes but it's quite hidden information.

    personally i lost 2 hours before thinking to this solution, and when i'm ready to tell to the world, i found some little references in stackoverflow comments and here in the last row 😆

  10. say5 commented on Mar 31, 2025

    @say5

    Would be nice to have something like this:

    1. op remove: path /roles/-/name/foobar
    2. op replace: path /roles/-/name/foobar value: {SOMETHING}
    3. op merge: path /roles/-/name/foobar value: {SOMETHING} (partial merge where SOMETHING overrides matching keys).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions