selection of multiple values

673 views
Skip to first unread message

Oleg Sukhoroslov

unread,
Nov 13, 2009, 3:18:23 AM11/13/09
to JSON Schema
Hi,

What is the best way to define an array property which can contain
only values from the predefined list? It is similar to enum, but
should allow selection of multiple values.

Regards,
Oleg

Seth Wessitsh

unread,
Nov 13, 2009, 3:40:01 AM11/13/09
to json-...@googlegroups.com
I'm thinking you'd need to create your enum type and then specify that as the type for some or all items of the array.  For example:

{
    type: "array",
    items: {type: "string", enum: ["a", "b", "c"] }
}

You could use referencing to reference the type rather than including it directly within the schema.

I realize you asked for the best way, not sure if this is it.  As far as I know it's the only way, but I wouldn't be surprised if I were wrong about that because I didn't put that much thought into it.

Anyway, hopefully this is useful to you in some way.  I apologize if it isn't.

Seth C. Wessitsh
se...@wessitsh.com

Oleg Sukhoroslov

unread,
Nov 13, 2009, 3:49:45 AM11/13/09
to JSON Schema
Seth,
The way you described is exacty what I was looking for =)
Thank you for a quick reply!

Regards,
Oleg

On Nov 13, 11:40 am, Seth Wessitsh <s...@wessitsh.com> wrote:
> I'm thinking you'd need to create your enum type and then specify that as
> the type for some or all items of the array.  For example:
>
> {
>     type: "array",
>     items: {type: "string", enum: ["a", "b", "c"] }
>
> }
>
> You could use referencing to reference the type rather than including it
> directly within the schema.
>
> I realize you asked for the best way, not sure if this is it.  As far as I
> know it's the only way, but I wouldn't be surprised if I were wrong about
> that because I didn't put that much thought into it.
>
> Anyway, hopefully this is useful to you in some way.  I apologize if it
> isn't.
>
> Seth C. Wessitsh
> s...@wessitsh.com
>
> On Fri, Nov 13, 2009 at 12:18 AM, Oleg Sukhoroslov <
>

Seth Wessitsh

unread,
Nov 13, 2009, 3:51:56 AM11/13/09
to json-...@googlegroups.com
My pleasure. :-)

Seth C. Wessitsh
se...@wessitsh.com

Oleg Sukhoroslov

unread,
Nov 13, 2009, 4:02:54 AM11/13/09
to JSON Schema
There's a slight caveat that formally one can select a single value
multiple times, like ["a", "a", "a"].
Is there any way to forbid it in schema, like specifiying that array
items must be unique?

On Nov 13, 11:40 am, Seth Wessitsh <s...@wessitsh.com> wrote:
> I'm thinking you'd need to create your enum type and then specify that as
> the type for some or all items of the array.  For example:
>
> {
>     type: "array",
>     items: {type: "string", enum: ["a", "b", "c"] }
>
> }
>
> You could use referencing to reference the type rather than including it
> directly within the schema.
>
> I realize you asked for the best way, not sure if this is it.  As far as I
> know it's the only way, but I wouldn't be surprised if I were wrong about
> that because I didn't put that much thought into it.
>
> Anyway, hopefully this is useful to you in some way.  I apologize if it
> isn't.
>
> Seth C. Wessitsh
> s...@wessitsh.com
>
> On Fri, Nov 13, 2009 at 12:18 AM, Oleg Sukhoroslov <
>

Seth Wessitsh

unread,
Nov 13, 2009, 5:15:52 AM11/13/09
to json-...@googlegroups.com
Unfortunately, I can't think of any straight forward way to specify that.  Certainly there are no restrictions which will allow you to specify that an array have unique elements (though it might be a good idea to add that).  There may be some convoluted way to do it that I'm not seeing but I'm fairly sure that's not the case.  In terms of a convoluted way, even if one were to specify the types of the array individually in the items restriction you'd still have to know the value the value to be used for the first element and eliminate it for the next type, and then for the next, etc., which could only be done dynamically.  E.g., this wouldn't work statically, but would be one incarnation of the schema if it were to be generated dynamically, given that the user had "a" for the first element "b" for the second and finally only "c" would be allowed in the last element.

{
    type: "array",
    items: [
        {type: "string", enum: ["a", "b", "c"]},
        {type: "string", enum: ["b", "c"]},
        {type: "string", enum: ["c"]}
    ]
}

Obviously this would be ridiculous to do dynamically as well since if you had to write some code to do it you may as well do something more direct/efficient.

Given that there are a fixed number of values in the enum and you desire that each element be unique you could reduce the number of false positives by including the maxItems restriction, for example:

{
    type: "array",
    items: {type: "string", enum: ["a", "b", "c"]},
   maxItems: 3
}

Obviously this isn't sufficient at all but it's better than not including it.

Seth C. Wessitsh
se...@wessitsh.com

Seth Wessitsh

unread,
Nov 13, 2009, 2:14:36 PM11/13/09
to json-...@googlegroups.com
Actually, Just after I posted the previous message when I had shut off my computer and was going to sleep I realized that it could be done in a convoluted way.  I'm going to write off my slow arrival to this solution as being tired.  Anyway, this would be ridiculous to do but it would work.  One type for each possible combination of picks placed in a union type.  Horrible I know. X-D

{
    type: [

        {
            type: "array",
            items: [
                {type: "string", enum: ["a", "b", "c"]},
                {type: "string", enum: ["b", "c"]},
                 {type: "string", enum: ["c"]}
            ],
            additionalProperties: false
        },

        {
            type: "array",
            items: [
                {type: "string", enum: ["a", "b", "c"]},
                {type: "string", enum: ["b", "c"]},
                 {type: "string", enum: ["b"]}
            ],
            additionalProperties: false
        },

        {
            type: "array",
            items: [
                {type: "string", enum: ["a", "b", "c"]},
                {type: "string", enum: ["a", "c"]},

                 {type: "string", enum: ["c"]}
            ],
            additionalProperties: false
        },

        {
            type: "array",
            items: [
                {type: "string", enum: ["a", "b", "c"]},
                {type: "string", enum: ["a", "c"]},
                 {type: "string", enum: ["a"]}
            ],
            additionalProperties: false
        },

        {
            type: "array",
            items: [
                {type: "string", enum: ["a", "b", "c"]},
                {type: "string", enum: ["a", "b"]},

                 {type: "string", enum: ["b"]}
            ],
            additionalProperties: false
        },

        {
            type: "array",
            items: [
                {type: "string", enum: ["a", "b", "c"]},
                {type: "string", enum: ["a", "b"]},
                 {type: "string", enum: ["a"]}
            ],
            additionalProperties: false
        },
    ]
}

Seth C. Wessitsh
se...@wessitsh.com

Oleg Sukhoroslov

unread,
Nov 16, 2009, 10:10:55 AM11/16/09
to json-...@googlegroups.com
It looks like a nightmare indeed 0_o
IMHO the simpliest way to differentiate between the cases when duplicate
values are acceptable or not is to use schema attribute specifying that
array elements are unique.
As far as I can see JSON Schema doesn't have such an attribute.
Sounds like a feature request? What do you think?
> se...@wessitsh.com <mailto:se...@wessitsh.com>
> se...@wessitsh.com <mailto:se...@wessitsh.com>
>
>
>
> On Fri, Nov 13, 2009 at 1:02 AM, Oleg Sukhoroslov
> <oleg.suk...@gmail.com <mailto:oleg.suk...@gmail.com>>
> wrote:
>
>
> There's a slight caveat that formally one can select a single
> value
> multiple times, like ["a", "a", "a"].
> Is there any way to forbid it in schema, like specifiying that
> array
> items must be unique?
>
> On Nov 13, 11:40 am, Seth Wessitsh <s...@wessitsh.com
> <mailto:s...@wessitsh.com>> wrote:
> > I'm thinking you'd need to create your enum type and then
> specify that as
> > the type for some or all items of the array. For example:
> >
> > {
> > type: "array",
> > items: {type: "string", enum: ["a", "b", "c"] }
> >
> > }
> >
> > You could use referencing to reference the type rather than
> including it
> > directly within the schema.
> >
> > I realize you asked for the best way, not sure if this is
> it. As far as I
> > know it's the only way, but I wouldn't be surprised if I
> were wrong about
> > that because I didn't put that much thought into it.
> >
> > Anyway, hopefully this is useful to you in some way. I
> apologize if it
> > isn't.
> >
> > Seth C. Wessitsh
> > s...@wessitsh.com <mailto:s...@wessitsh.com>
> >
> > On Fri, Nov 13, 2009 at 12:18 AM, Oleg Sukhoroslov <
> >
> > oleg.sukhoros...@gmail.com

Seth Wessitsh

unread,
Nov 16, 2009, 1:37:05 PM11/16/09
to json-...@googlegroups.com
I agree, I think that would definitely be the best way.  That'll have to take that up with Kris Zyp, the originator of the JSON Schema proposal.  Perhaps a comment to the proposal itself might get his attention if he hasn't been reading this thread.

Seth C. Wessitsh
se...@wessitsh.com

Kris Zyp

unread,
Nov 16, 2009, 1:52:17 PM11/16/09
to json-...@googlegroups.com
Yes, I have been following the thread, and that does seem like a
reasonable addition to me. FWIW, I am working on creating a new draft
that follows IETF's RFC format, and have been trying to collect various
corrections and additions in there.
Thanks,
Kris

Seth Wessitsh wrote:
> I agree, I think that would definitely be the best way. That'll have
> to take that up with Kris Zyp, the originator of the JSON Schema
> proposal. Perhaps a comment to the proposal itself might get his
> attention if he hasn't been reading this thread.
>
> Seth C. Wessitsh
> se...@wessitsh.com <mailto:se...@wessitsh.com>
> <mailto:se...@wessitsh.com <mailto:se...@wessitsh.com>>
> >
> >
> > On Fri, Nov 13, 2009 at 2:15 AM, Seth Wessitsh
> <se...@wessitsh.com <mailto:se...@wessitsh.com>
> <mailto:se...@wessitsh.com <mailto:se...@wessitsh.com>>
> >
> >
> >
> > On Fri, Nov 13, 2009 at 1:02 AM, Oleg Sukhoroslov
> > <oleg.suk...@gmail.com
> <mailto:oleg.suk...@gmail.com>
> <mailto:oleg.suk...@gmail.com
> <mailto:oleg.suk...@gmail.com>>>
> > wrote:
> >
> >
> > There's a slight caveat that formally one can select a
> single
> > value
> > multiple times, like ["a", "a", "a"].
> > Is there any way to forbid it in schema, like
> specifiying that
> > array
> > items must be unique?
> >
> > On Nov 13, 11:40 am, Seth Wessitsh <s...@wessitsh.com
> <mailto:s...@wessitsh.com>
> > <mailto:s...@wessitsh.com <mailto:s...@wessitsh.com>>>
> wrote:
> > > I'm thinking you'd need to create your enum type and then
> > specify that as
> > > the type for some or all items of the array. For example:
> > >
> > > {
> > > type: "array",
> > > items: {type: "string", enum: ["a", "b", "c"] }
> > >
> > > }
> > >
> > > You could use referencing to reference the type rather
> than
> > including it
> > > directly within the schema.
> > >
> > > I realize you asked for the best way, not sure if this is
> > it. As far as I
> > > know it's the only way, but I wouldn't be surprised if I
> > were wrong about
> > > that because I didn't put that much thought into it.
> > >
> > > Anyway, hopefully this is useful to you in some way. I
> > apologize if it
> > > isn't.
> > >
> > > Seth C. Wessitsh
> > > s...@wessitsh.com <mailto:s...@wessitsh.com>
> <mailto:s...@wessitsh.com <mailto:s...@wessitsh.com>>
> > >
> > > On Fri, Nov 13, 2009 at 12:18 AM, Oleg Sukhoroslov <
> > >
> > > oleg.sukhoros...@gmail.com
> <mailto:oleg.sukhoros...@gmail.com>
> > <mailto:oleg.sukhoros...@gmail.com

Seth Wessitsh

unread,
Nov 16, 2009, 2:32:03 PM11/16/09
to json-...@googlegroups.com
Thank you, Kris.

Seth C. Wessitsh
se...@wessitsh.com

Oleg Sukhoroslov

unread,
Nov 16, 2009, 2:52:23 PM11/16/09
to json-...@googlegroups.com
Great! Thank you, Seth and Kris.
Reply all
Reply to author
Forward
0 new messages