Replies: 14 comments 11 replies
-
Would be very useful! |
Beta Was this translation helpful? Give feedback.
-
Having a z.array(z.string()).refine(items => new Set(items).size === items.length, {
message: 'Must be an array of unique strings',
}) |
Beta Was this translation helpful? Give feedback.
-
I agree @joaoGabriel55, it would be very useful! |
Beta Was this translation helpful? Give feedback.
-
Has there been any update on this? Would be super useful to validate a unique array of primary keys without hitting the db layer. |
Beta Was this translation helpful? Give feedback.
-
I'm working on a solution for that. |
Beta Was this translation helpful? Give feedback.
-
No I meant that if the duplicate items array has many dense objects, logging them would be expensive.
On Sep 14, 2023, at 2:22 AM, ValTashkov ***@***.***> wrote:
I don't see where we would need JSON.stringify in this example, even with nested objects
We add second argument to the method, that is a callback that takes as first argument an array of the duplicated items. After that you can do whatever you like. In my case I am mapping the array of user to just the names
—
Reply to this email directly, view it on GitHub<#2316 (reply in thread)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AKO6F3JCQXNYPDLWTJD6ZN3X2KPDPANCNFSM6AAAAAAWZBHTTA>.
You are receiving this because you commented.Message ID: ***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
Made a simple helper: import z from 'zod';
function zUniqueArray<
ArrSchema extends z.ZodArray<z.ZodTypeAny, 'many'>,
UniqueVal
>(
uniqueBy: (item: z.infer<ArrSchema>[number]) => UniqueVal,
schema: ArrSchema
) {
return schema.superRefine((items, ctx) => {
const seen = new Set<UniqueVal>();
for (const [i, item] of items.entries()) {
const val = uniqueBy(item);
if (seen.has(val)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `Unique property validation failed`,
path: [i],
});
} else {
seen.add(val);
}
}
});
}
const uniqueIdSchema = zUniqueArray(
(obj) => obj.id,
z.array(z.object({ id: z.number() }))
);
// succeeds
console.log(uniqueIdSchema.safeParse([{ id: 1 }, { id: 2 }]));
// fails
console.log(uniqueIdSchema.safeParse([{ id: 1 }, { id: 1 }])); |
Beta Was this translation helpful? Give feedback.
-
I didn't read the discussion much. I am using this z.array().transform((data) => uniq(data)) |
Beta Was this translation helpful? Give feedback.
-
Another way is to use superRefine as per the docs: https://zod.dev/?id=superrefine const Strings = z.array(z.string()).superRefine((val, ctx) => {
if (val.length !== new Set(val).size) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: `No duplicates allowed.`,
});
}
}); |
Beta Was this translation helpful? Give feedback.
-
This works. How would you then validate each item of the array, to e.g. display an error message at that input field that had caused the "duplication"? |
Beta Was this translation helpful? Give feedback.
-
I had to change this part from |
Beta Was this translation helpful? Give feedback.
-
You can combine const itemSchema = z.object({
prop: z.string()
})
items: z
.array(itemSchema)
.refine(items => _.isEqual(items, _.uniqBy(items, 'prop'))) |
Beta Was this translation helpful? Give feedback.
-
A more generalized version (based on the past answer of @HassanZahirnia). function uniqueArray(schema: ZodType) {
return z
.array(schema)
.refine((items) => new Set(items).size === items.length, {
message: 'All items must be unique, no duplicate values allowed',
});
}
const schema = {
setString: uniqueArray(z.string().minLength(87)),
setNumber: uniqueArray(z.number()),
setBoolean: uniqueArray(z.boolean()),
} |
Beta Was this translation helpful? Give feedback.
-
I just found out that zod has Sets, which might be more what someone would like to use instead of array with uniquness. |
Beta Was this translation helpful? Give feedback.
-
I was checking the docs to see if there was any way to validate if there was any duplicate items on an array, perhaps we could implement a
unique()
function that does just that for arrays?Or for more complex arrays:
Is this doable or is it out of scope?
Beta Was this translation helpful? Give feedback.
All reactions