diff --git a/packages/shared/useArrayFind/index.md b/packages/shared/useArrayFind/index.md new file mode 100644 index 00000000000..9f6092f688c --- /dev/null +++ b/packages/shared/useArrayFind/index.md @@ -0,0 +1,29 @@ +--- +category: Array +--- + +# useArrayFind + +Reactive `Array.find`. + +## Usage + +```js +import { useArrayFind } from '@vueuse/core' + +const list = [ref(1), ref(-1), ref(2)] +const positive = useArrayFind(list, val => val > 0) +// positive.value: 1 +``` + +### Use with reactive array + +```js +import { useArrayFind } from '@vueuse/core' + +const list = reactive([-1, -2]) +const positive = useArrayFind(list, val => val > 0) +// positive.value: undefined +list.push(1) +// positive.value: 1 +``` diff --git a/packages/shared/useArrayFind/index.test.ts b/packages/shared/useArrayFind/index.test.ts new file mode 100644 index 00000000000..0dc72dbea9a --- /dev/null +++ b/packages/shared/useArrayFind/index.test.ts @@ -0,0 +1,35 @@ +import { reactive, ref } from 'vue-demi' +import { useSetup } from '../../.test' +import { useArrayFind } from '../useArrayFind' + +describe('useArrayFind', () => { + it('should be defined', () => { + expect(useArrayFind).toBeDefined() + }) + + it('should find postive', () => { + useSetup(() => { + const item1 = ref(1) + const item2 = ref(2) + const item3 = ref(3) + const positive = useArrayFind([item1, item2, item3], val => val > 0) + expect(positive.value).toBe(1) + item1.value = -1 + expect(positive.value).toBe(2) + item2.value = -1 + expect(positive.value).toBe(3) + item3.value = -1 + expect(positive.value).toBe(undefined) + }) + }) + + it('should work with reactive array', () => { + useSetup(() => { + const list = reactive([-1, -2]) + const positive = useArrayFind(list, val => val > 0) + expect(positive.value).toBe(undefined) + list.push(1) + expect(positive.value).toBe(1) + }) + }) +}) diff --git a/packages/shared/useArrayFind/index.ts b/packages/shared/useArrayFind/index.ts new file mode 100644 index 00000000000..8cf0fc24def --- /dev/null +++ b/packages/shared/useArrayFind/index.ts @@ -0,0 +1,16 @@ +import type { MaybeComputedRef } from '@vueuse/shared' +import type { ComputedRef } from 'vue-demi' +import { resolveUnref } from '@vueuse/shared' +import { computed } from 'vue-demi' + +export function useArrayFind( + list: MaybeComputedRef[]>, + fn: (element: T, index: number, array: MaybeComputedRef[]) => boolean, +): ComputedRef { + return computed(() => + resolveUnref( + resolveUnref(list) + .find((element, index, array) => fn(resolveUnref(element), index, array)), + ), + ) +}