Skip to content

Commit

Permalink
feat(useArrayDifference): new function (#2710)
Browse files Browse the repository at this point in the history
  • Loading branch information
Alfred-Skyblue committed Mar 4, 2023
1 parent 526d5c7 commit a2a338d
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/shared/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export * from './tryOnMounted'
export * from './tryOnScopeDispose'
export * from './tryOnUnmounted'
export * from './until'
export * from './useArrayDifference'
export * from './useArrayEvery'
export * from './useArrayFilter'
export * from './useArrayFind'
Expand Down
33 changes: 33 additions & 0 deletions packages/shared/useArrayDifference/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
category: Array
---

# useArrayDifference

Reactive get array difference of two array

## Usage

### Use with reactive array

```js
import { useArrayDifference } from '@vueuse/core'
const list1 = ref([0, 1, 2, 3, 4, 5])
const list2 = ref([4, 5, 6])
const result = useArrayDifference(list1, list2)
// result.value: [0, 1, 2, 3]
list2.value = [0, 1, 2]
// result.value: [3, 4, 5]
```

### Use with reactive array and use function comparison

```js
import { useArrayDifference } from '@vueuse/core'

const list1 = ref([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }])
const list2 = ref([{ id: 4 }, { id: 5 }, { id: 6 }])

const result = useArrayDifference(list1, list2, value => a.id)
// result.value: [{ id: 1 }, { id: 2 }, { id: 3 }]
```
50 changes: 50 additions & 0 deletions packages/shared/useArrayDifference/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { ref } from 'vue-demi'
import { useArrayDifference } from './index'

describe('useArrayDifference', () => {
it('should be defined', () => {
expect(useArrayDifference).toBeDefined()
})
it('should return the difference of two array', () => {
const list1 = ref([1, 2, 3, 4, 5])
const list2 = ref([4, 5, 6])

const result = useArrayDifference(list1, list2)
expect(result.value).toEqual([1, 2, 3])

list2.value = [1, 2, 3]
expect(result.value).toEqual([4, 5])

list1.value = [1, 2, 3]
expect(result.value).toEqual([])
})

it('should return the difference of two array with iteratee', () => {
const list1 = ref([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }])
const list2 = ref([{ id: 4 }, { id: 5 }])

const result = useArrayDifference(list1, list2, (value, othVal) => value.id === othVal.id)
expect(result.value).toEqual([{ id: 1 }, { id: 2 }, { id: 3 }])

list2.value = [{ id: 1 }, { id: 2 }, { id: 3 }]
expect(result.value).toEqual([{ id: 4 }, { id: 5 }])

list1.value = [{ id: 1 }, { id: 2 }, { id: 3 }]
expect(result.value).toEqual([])
})

// key
it('should return the difference of two array with key', () => {
const list1 = ref([{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }])
const list2 = ref([{ id: 3 }, { id: 4 }, { id: 5 }])

const result = useArrayDifference(list1, list2, 'id')
expect(result.value).toEqual([{ id: 1 }, { id: 2 }])

list2.value = [{ id: 1 }, { id: 2 }]
expect(result.value).toEqual([{ id: 3 }, { id: 4 }, { id: 5 }])

list1.value = [{ id: 1 }, { id: 2 }]
expect(result.value).toEqual([])
})
})
29 changes: 29 additions & 0 deletions packages/shared/useArrayDifference/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import type { ComputedRef } from 'vue-demi'
import { computed } from 'vue-demi'
import { isString } from '../utils'
import type { MaybeComputedRef } from '../utils'
import { resolveUnref } from '../resolveUnref'

const defaultComparator = <T>(value: T, othVal: T) =>
value === othVal

export function useArrayDifference<T>(list: MaybeComputedRef<T[]>, values: MaybeComputedRef<T[]>, key?: keyof T): ComputedRef<T[]>
export function useArrayDifference<T>(list: MaybeComputedRef<T[]>, values: MaybeComputedRef<T[]>, compareFn?: (value: T, othVal: T) => boolean): ComputedRef<T[]>

/**
* Reactive get array difference of two array
* @see https://vueuse.org/useArrayDifference
* @returns {Array} - the difference of two array
* @param args
*/
export function useArrayDifference<T>(...args: any[]): ComputedRef<T[]> {
const list: MaybeComputedRef<T[]> = args[0]
const values: MaybeComputedRef<T[]> = args[1]
let compareFn = args[2] ?? defaultComparator

if (isString(compareFn)) {
const key = compareFn as keyof T
compareFn = (value: T, othVal: T) => value[key] === othVal[key]
}
return computed(() => resolveUnref(list).filter(x => !resolveUnref(values).find(y => compareFn(x, y))))
}

0 comments on commit a2a338d

Please sign in to comment.