Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(useArrayIncludes): new function (#2708)
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
- Loading branch information
1 parent
a2a338d
commit 4d6bc00
Showing
4 changed files
with
132 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
--- | ||
category: Array | ||
--- | ||
|
||
# useArrayIncludes | ||
|
||
Reactive `Array.includes` | ||
|
||
## Usage | ||
|
||
### Use with reactive array | ||
|
||
```js | ||
import { useArrayIncludes } from '@vueuse/core' | ||
const list = ref([0, 2, 4, 6, 8]) | ||
const result = useArrayIncludes(list, 10) | ||
// result.value: false | ||
list.value.push(10) | ||
// result.value: true | ||
list.value.pop() | ||
// result.value: false | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { ref } from 'vue-demi' | ||
import { useArrayIncludes } from './index' | ||
|
||
describe('useArrayIncludes', () => { | ||
it('should be defined', () => { | ||
expect(useArrayIncludes).toBeDefined() | ||
}) | ||
|
||
it('should work with array of refs', () => { | ||
const array = ref([0, 2, 4, 6]) | ||
const result = useArrayIncludes(array, 8) | ||
expect(result.value).toBeFalsy() | ||
array.value.push(8) | ||
expect(result.value).toBeTruthy() | ||
array.value.pop() | ||
expect(result.value).toBeFalsy() | ||
}) | ||
|
||
it('should work with array of refs and comparator', () => { | ||
const array = ref([{ id: 1 }, { id: 2 }, { id: 3 }]) | ||
const result = useArrayIncludes(array, 3, 'id') | ||
expect(result.value).toBeTruthy() | ||
array.value.pop() | ||
expect(result.value).toBeFalsy() | ||
}) | ||
|
||
it('should work with array of refs and comparatorFn', () => { | ||
const array = ref([{ id: 1 }, { id: 2 }, { id: 3 }]) | ||
const result = useArrayIncludes(array, { id: 3 }, (element, value) => element.id === value.id) | ||
expect(result.value).toBeTruthy() | ||
array.value.pop() | ||
expect(result.value).toBeFalsy() | ||
}) | ||
|
||
it('should work with array of refs and fromIndex', () => { | ||
const array = ref([{ id: 1 }, { id: 2 }, { id: 3 }]) | ||
const result = useArrayIncludes(array, { id: 1 }, { fromIndex: 1, comparator: (element, value) => element.id === value.id }) | ||
expect(result.value).toBeFalsy() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import type { ComputedRef } from 'vue-demi' | ||
import { computed } from 'vue-demi' | ||
import { containsProp, isObject } from '../utils' | ||
import type { MaybeComputedRef } from '../utils' | ||
import { resolveUnref } from '../resolveUnref' | ||
|
||
export type UseArrayIncludesComparatorFn<T, V> = ((element: T, value: V, index: number, array: MaybeComputedRef<T>[]) => boolean) | ||
|
||
function isArrayIncludesOptions<T, V>(obj: any): obj is UseArrayIncludesOptions<T, V> { | ||
return isObject(obj) && containsProp(obj, 'formIndex', 'comparator') | ||
} | ||
|
||
export interface UseArrayIncludesOptions<T, V> { | ||
fromIndex?: number | ||
comparator?: UseArrayIncludesComparatorFn<T, V> | keyof T | ||
} | ||
|
||
export function useArrayIncludes<T, V = any>( | ||
list: MaybeComputedRef<MaybeComputedRef<T>[]>, | ||
value: MaybeComputedRef<V>, | ||
comparator?: UseArrayIncludesComparatorFn<T, V>, | ||
): ComputedRef<boolean> | ||
export function useArrayIncludes<T, V = any>( | ||
list: MaybeComputedRef<MaybeComputedRef<T>[]>, | ||
value: MaybeComputedRef<V>, | ||
comparator?: keyof T, | ||
): ComputedRef<boolean> | ||
export function useArrayIncludes<T, V = any>( | ||
list: MaybeComputedRef<MaybeComputedRef<T>[]>, | ||
value: MaybeComputedRef<V>, | ||
options?: UseArrayIncludesOptions<T, V>, | ||
): ComputedRef<boolean> | ||
/** | ||
* Reactive `Array.includes` | ||
* | ||
* @see https://vueuse.org/useArrayIncludes | ||
* | ||
* @returns {boolean} true if the `value` is found in the array. Otherwise, false. | ||
* @param args | ||
*/ | ||
export function useArrayIncludes<T, V = any>( | ||
...args: any[] | ||
): ComputedRef<boolean> { | ||
const list: MaybeComputedRef<MaybeComputedRef<T>[]> = args[0] | ||
const value: MaybeComputedRef<V> = args[1] | ||
|
||
let comparator: UseArrayIncludesComparatorFn<T, V> = args[2] | ||
let formIndex = 0 | ||
|
||
if (isArrayIncludesOptions(comparator)) { | ||
formIndex = comparator.fromIndex ?? 0 | ||
comparator = comparator.comparator! | ||
} | ||
|
||
if (typeof comparator === 'string') { | ||
const key = comparator as keyof T | ||
comparator = (element: T, value: V) => element[key] === resolveUnref(value) | ||
} | ||
|
||
comparator = comparator ?? ((element: T, value: T) => element === resolveUnref(value)) | ||
|
||
return computed(() => | ||
resolveUnref(list) | ||
.slice(formIndex) | ||
.some((element, index, array) => | ||
comparator(resolveUnref(element), resolveUnref(value), index, resolveUnref(array)), | ||
), | ||
) | ||
} |