Skip to content

sift

過濾數組中的假值(falsy values),返回一個新數組。

基礎用法

typescript
import { sift } from 'radash'

const mixedArray = [0, 1, false, 2, '', 3, null, 4, undefined, 5, NaN]

const filtered = sift(mixedArray)
// [1, 2, 3, 4, 5]

語法

typescript
function sift<T>(array: readonly T[]): NonNullable<T>[]

參數

  • array (readonly T[]): 要過濾的數組

返回值

返回一個新數組,包含所有非假值元素。

示例

過濾基本假值

typescript
import { sift } from 'radash'

const array = [0, 1, false, 2, '', 3, null, 4, undefined, 5, NaN]

const filtered = sift(array)
// [1, 2, 3, 4, 5]

過濾字符串數組

typescript
import { sift } from 'radash'

const strings = ['hello', '', 'world', '   ', 'javascript', null, 'typescript']

const filtered = sift(strings)
// ['hello', 'world', 'javascript', 'typescript']

過濾數字數組

typescript
import { sift } from 'radash'

const numbers = [0, 1, 2, 3, 4, 5, NaN, 6, 7, 8, 9, 10]

const filtered = sift(numbers)
// [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] (移除了0和NaN)

過濾對象數組

typescript
import { sift } from 'radash'

const users = [
  { id: 1, name: 'Alice' },
  null,
  { id: 2, name: 'Bob' },
  undefined,
  { id: 3, name: 'Charlie' },
  false
]

const filtered = sift(users)
// [
//   { id: 1, name: 'Alice' },
//   { id: 2, name: 'Bob' },
//   { id: 3, name: 'Charlie' }
// ]

過濾混合類型數組

typescript
import { sift } from 'radash'

const mixed = [
  'hello',
  0,
  { key: 'value' },
  false,
  [1, 2, 3],
  '',
  null,
  undefined,
  NaN,
  true
]

const filtered = sift(mixed)
// [
//   'hello',
//   { key: 'value' },
//   [1, 2, 3],
//   true
// ]

處理嵌套數組

typescript
import { sift } from 'radash'

const nested = [
  [1, 2, 3],
  null,
  [4, 5, 6],
  undefined,
  [7, 8, 9]
]

const filtered = sift(nested)
// [
//   [1, 2, 3],
//   [4, 5, 6],
//   [7, 8, 9]
// ]

處理函數數組

typescript
import { sift } from 'radash'

const functions = [
  () => 'hello',
  null,
  (x: number) => x * 2,
  undefined,
  () => 'world'
]

const filtered = sift(functions)
// [
//   () => 'hello',
//   (x: number) => x * 2,
//   () => 'world'
// ]

在API響應處理中使用

typescript
import { sift } from 'radash'

interface ApiResponse {
  data: (User | null)[]
  total: number
}

interface User {
  id: number
  name: string
  email: string
}

function processApiResponse(response: ApiResponse) {
  const validUsers = sift(response.data)
  
  return {
    users: validUsers,
    total: validUsers.length
  }
}

const response: ApiResponse = {
  data: [
    { id: 1, name: 'Alice', email: 'alice@example.com' },
    null,
    { id: 2, name: 'Bob', email: 'bob@example.com' },
    undefined,
    { id: 3, name: 'Charlie', email: 'charlie@example.com' }
  ],
  total: 5
}

const processed = processApiResponse(response)
console.log(processed.users.length) // 3 (移除了null和undefined)

處理表單數據

typescript
import { sift } from 'radash'

function processFormData(formData: Record<string, any>) {
  const values = Object.values(formData)
  const validValues = sift(values)
  
  return validValues.length > 0 ? validValues : ['No valid data']
}

const formData = {
  name: 'John',
  email: '',
  age: 25,
  phone: null,
  address: '   ',
  city: 'New York'
}

const validData = processFormData(formData)
console.log(validData) // ['John', 25, 'New York']

處理配置對象

typescript
import { sift } from 'radash'

function mergeConfigs(...configs: Record<string, any>[]) {
  const allValues = configs.flatMap(config => Object.values(config))
  const validValues = sift(allValues)
  
  return validValues
}

const config1 = { theme: 'dark', language: null, notifications: true }
const config2 = { theme: undefined, language: 'en', sound: false }

const merged = mergeConfigs(config1, config2)
console.log(merged) // ['dark', true, 'en', false]

處理事件監聽器

typescript
import { sift } from 'radash'

class EventEmitter {
  private listeners: Record<string, (Function | null)[]> = {}

  on(event: string, listener: Function) {
    if (!this.listeners[event]) {
      this.listeners[event] = []
    }
    this.listeners[event].push(listener)
  }

  off(event: string, listener: Function) {
    if (this.listeners[event]) {
      const index = this.listeners[event].indexOf(listener)
      if (index > -1) {
        this.listeners[event][index] = null
      }
    }
  }

  emit(event: string, ...args: any[]) {
    if (this.listeners[event]) {
      const validListeners = sift(this.listeners[event])
      validListeners.forEach(listener => listener(...args))
    }
  }
}

const emitter = new EventEmitter()
const listener1 = (data: any) => console.log('Listener 1:', data)
const listener2 = (data: any) => console.log('Listener 2:', data)

emitter.on('test', listener1)
emitter.on('test', listener2)
emitter.off('test', listener1)

emitter.emit('test', 'Hello') // 只輸出: Listener 2: Hello

處理數據庫查詢結果

typescript
import { sift } from 'radash'

interface DatabaseResult {
  id: number
  name: string
  value: number | null
}

function processDatabaseResults(results: DatabaseResult[]) {
  const validResults = sift(results)
  
  return {
    total: validResults.length,
    average: validResults.reduce((sum, result) => sum + result.value, 0) / validResults.length
  }
}

const results: DatabaseResult[] = [
  { id: 1, name: 'Item 1', value: 10 },
  { id: 2, name: 'Item 2', value: null },
  { id: 3, name: 'Item 3', value: 20 },
  { id: 4, name: 'Item 4', value: 30 }
]

const processed = processDatabaseResults(results)
console.log(processed) // { total: 3, average: 20 }

注意事項

  1. 假值過濾: 移除所有假值(false, 0, '', null, undefined, NaN)
  2. 保持原數組不變: sift 不會修改原數組,而是返回新的數組
  3. 類型安全: 返回的數組類型是 NonNullable<T>[]
  4. 性能: 時間復雜度為 O(n),其中 n 是數組長度
  5. 空數組: 如果原數組為空或只包含假值,返回空數組

與其他方法的區別

  • filter(): 需要提供過濾函數,sift 自動過濾假值
  • compact(): 類似功能,但 sift 更簡潔
  • Array.prototype.filter(Boolean): 功能相同,但 sift 更直觀

實際應用場景

  1. 數據清理: 清理API響應中的無效數據
  2. 表單驗證: 過濾表單中的空值
  3. 配置處理: 合並配置時過濾無效值
  4. 事件處理: 清理事件監聽器數組
  5. 數據庫查詢: 處理可能包含null的查詢結果

Released under the MIT License.