Skip to content

zip

將多個數組壓縮成一個數組。

基礎用法

typescript
import { zip } from 'radash'

const names = ['Alice', 'Bob', 'Charlie']
const ages = [25, 30, 35]
const cities = ['Beijing', 'Shanghai', 'Guangzhou']

const zipped = zip(names, ages, cities)
// [
//   ['Alice', 25, 'Beijing'],
//   ['Bob', 30, 'Shanghai'],
//   ['Charlie', 35, 'Guangzhou']
// ]

語法

typescript
function zip<T extends readonly unknown[]>(
  ...arrays: T
): Array<{ [K in keyof T]: T[K] extends readonly (infer U)[] ? U : never }>

參數

  • ...arrays (T): 要組合的數組,可以傳入任意數量的數組

返回值

返回一個數組,每個元素是輸入數組對應位置的元素組成的元組。

示例

基本組合

typescript
import { zip } from 'radash'

const letters = ['a', 'b', 'c']
const numbers = [1, 2, 3]

const zipped = zip(letters, numbers)
// [
//   ['a', 1],
//   ['b', 2],
//   ['c', 3]
// ]

組合三個數組

typescript
import { zip } from 'radash'

const fruits = ['apple', 'banana', 'cherry']
const colors = ['red', 'yellow', 'red']
const prices = [1.5, 2.0, 3.0]

const zipped = zip(fruits, colors, prices)
// [
//   ['apple', 'red', 1.5],
//   ['banana', 'yellow', 2.0],
//   ['cherry', 'red', 3.0]
// ]

處理不同長度的數組

typescript
import { zip } from 'radash'

const short = [1, 2]
const long = ['a', 'b', 'c', 'd']

const zipped = zip(short, long)
// [
//   [1, 'a'],
//   [2, 'b']
// ] (以最短數組的長度為准)

組合對象數組

typescript
import { zip } from 'radash'

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

const scores = [85, 92, 78]

const zipped = zip(users, scores)
// [
//   [{ id: 1, name: 'Alice' }, 85],
//   [{ id: 2, name: 'Bob' }, 92],
//   [{ id: 3, name: 'Charlie' }, 78]
// ]

創建鍵值對

typescript
import { zip } from 'radash'

const keys = ['name', 'age', 'city']
const values = ['Alice', 25, 'Beijing']

const zipped = zip(keys, values)
// [
//   ['name', 'Alice'],
//   ['age', 25],
//   ['city', 'Beijing']
// ]

// 轉換為對象
const obj = Object.fromEntries(zipped)
// { name: 'Alice', age: 25, city: 'Beijing' }

處理混合類型

typescript
import { zip } from 'radash'

const strings = ['hello', 'world']
const numbers = [1, 2]
const booleans = [true, false]
const objects = [{ key: 'value' }, { key: 'value2' }]

const zipped = zip(strings, numbers, booleans, objects)
// [
//   ['hello', 1, true, { key: 'value' }],
//   ['world', 2, false, { key: 'value2' }]
// ]

在數據處理中使用

typescript
import { zip } from 'radash'

interface DataPoint {
  timestamp: number
  value: number
  label: string
}

function processTimeSeriesData(timestamps: number[], values: number[], labels: string[]): DataPoint[] {
  const zipped = zip(timestamps, values, labels)
  
  return zipped.map(([timestamp, value, label]) => ({
    timestamp,
    value,
    label
  }))
}

const timestamps = [1000, 2000, 3000]
const values = [10, 20, 30]
const labels = ['point1', 'point2', 'point3']

const dataPoints = processTimeSeriesData(timestamps, values, labels)
console.log(dataPoints)
// [
//   { timestamp: 1000, value: 10, label: 'point1' },
//   { timestamp: 2000, value: 20, label: 'point2' },
//   { timestamp: 3000, value: 30, label: 'point3' }
// ]

創建表格數據

typescript
import { zip } from 'radash'

function createTable(headers: string[], ...columns: any[][]) {
  const zipped = zip(...columns)
  
  return {
    headers,
    rows: zipped
  }
}

const headers = ['Name', 'Age', 'City']
const names = ['Alice', 'Bob', 'Charlie']
const ages = [25, 30, 35]
const cities = ['Beijing', 'Shanghai', 'Guangzhou']

const table = createTable(headers, names, ages, cities)
console.log(table)
// {
//   headers: ['Name', 'Age', 'City'],
//   rows: [
//     ['Alice', 25, 'Beijing'],
//     ['Bob', 30, 'Shanghai'],
//     ['Charlie', 35, 'Guangzhou']
//   ]
// }

處理表單數據

typescript
import { zip } from 'radash'

function processFormData(fieldNames: string[], fieldValues: any[]) {
  const zipped = zip(fieldNames, fieldValues)
  
  return zipped.reduce((formData, [name, value]) => {
    formData[name] = value
    return formData
  }, {} as Record<string, any>)
}

const fieldNames = ['name', 'email', 'age', 'city']
const fieldValues = ['John Doe', 'john@example.com', 30, 'New York']

const formData = processFormData(fieldNames, fieldValues)
console.log(formData)
// {
//   name: 'John Doe',
//   email: 'john@example.com',
//   age: 30,
//   city: 'New York'
// }

創建坐標點

typescript
import { zip } from 'radash'

function createPoints(xCoords: number[], yCoords: number[]) {
  const zipped = zip(xCoords, yCoords)
  
  return zipped.map(([x, y], index) => ({
    id: index + 1,
    x,
    y
  }))
}

const xCoords = [1, 2, 3, 4, 5]
const yCoords = [2, 4, 6, 8, 10]

const points = createPoints(xCoords, yCoords)
console.log(points)
// [
//   { id: 1, x: 1, y: 2 },
//   { id: 2, x: 2, y: 4 },
//   { id: 3, x: 3, y: 6 },
//   { id: 4, x: 4, y: 8 },
//   { id: 5, x: 5, y: 10 }
// ]

處理API響應

typescript
import { zip } from 'radash'

interface ApiResponse {
  ids: number[]
  names: string[]
  emails: string[]
}

function processApiResponse(response: ApiResponse) {
  const { ids, names, emails } = response
  const zipped = zip(ids, names, emails)
  
  return zipped.map(([id, name, email]) => ({
    id,
    name,
    email
  }))
}

const apiResponse: ApiResponse = {
  ids: [1, 2, 3],
  names: ['Alice', 'Bob', 'Charlie'],
  emails: ['alice@example.com', 'bob@example.com', 'charlie@example.com']
}

const users = processApiResponse(apiResponse)
console.log(users)
// [
//   { id: 1, name: 'Alice', email: 'alice@example.com' },
//   { id: 2, name: 'Bob', email: 'bob@example.com' },
//   { id: 3, name: 'Charlie', email: 'charlie@example.com' }
// ]

創建枚舉映射

typescript
import { zip } from 'radash'

function createEnumMap(keys: string[], values: any[]) {
  const zipped = zip(keys, values)
  
  return zipped.reduce((enumMap, [key, value]) => {
    enumMap[key] = value
    return enumMap
  }, {} as Record<string, any>)
}

const statusKeys = ['PENDING', 'ACTIVE', 'INACTIVE', 'DELETED']
const statusValues = [0, 1, 2, 3]

const statusEnum = createEnumMap(statusKeys, statusValues)
console.log(statusEnum)
// {
//   PENDING: 0,
//   ACTIVE: 1,
//   INACTIVE: 2,
//   DELETED: 3
// }

處理CSV數據

typescript
import { zip } from 'radash'

function parseCSV(csvString: string) {
  const lines = csvString.trim().split('\n')
  const headers = lines[0].split(',')
  const dataLines = lines.slice(1)
  
  const columns = headers.map((_, columnIndex) =>
    dataLines.map(line => line.split(',')[columnIndex])
  
  const zipped = zip(...columns)
  
  return zipped.map(row => {
    const obj: Record<string, string> = {}
    headers.forEach((header, index) => {
      obj[header] = row[index]
    })
    return obj
  })
}

const csvData = `name,age,city
Alice,25,Beijing
Bob,30,Shanghai
Charlie,35,Guangzhou`

const parsed = parseCSV(csvData)
console.log(parsed)
// [
//   { name: 'Alice', age: '25', city: 'Beijing' },
//   { name: 'Bob', age: '30', city: 'Shanghai' },
//   { name: 'Charlie', age: '35', city: 'Guangzhou' }
// ]

注意事項

  1. 長度處理: 以最短數組的長度為准,超出部分會被忽略
  2. 保持原數組不變: zip 不會修改原數組,而是返回新的數組
  3. 類型安全: 返回的數組類型會根據輸入數組的類型推斷
  4. 性能: 時間復雜度為 O(n),其中 n 是最短數組的長度
  5. 空數組: 如果任何輸入數組為空,返回空數組

與其他方法的區別

  • map(): 只能處理單個數組
  • zip(): 可以同時處理多個數組
  • Array.from(): 需要手動創建索引映射
  • Object.fromEntries(): 只能創建鍵值對,而 zip 更靈活

實際應用場景

  1. 數據處理: 組合多個數據源的數據
  2. 表格創建: 將列數據轉換為行數據
  3. 坐標處理: 組合x和y坐標
  4. 表單處理: 將字段名和值配對
  5. API處理: 處理分離的數組響應

Released under the MIT License.