JavaScript 함수형 프로그래밍 예제 100선

기초 함수 → 배열 처리 → 불변성 → 고차 함수 → 실무 데이터 처리 → React 상태 패턴 순서로 정리.

1

1~20 함수 기본 / 배열

1. 일반 함수 → 화살표 함수

function add(a, b) {
  return a + b
}

const add2 = (a, b) => a + b

console.log(add2(10, 20)) // 30

2. 매개변수를 받아 값 반환

const double = num => num * 2

console.log(double(10)) // 20

3. 함수에서 객체 반환

const createUser = name => ({
  name: name,
  active: true
})

console.log(createUser('홍길동')) // { name: '홍길동', active: true }

4. 함수에서 배열 반환

const createNumbers = () => [1, 2, 3]

console.log(createNumbers()) // [1, 2, 3]

5. 기본 매개변수

const greet = (name = '사용자') => {
  return `안녕하세요 ${name}`
}

console.log(greet()) // '안녕하세요 사용자'

6. Rest Parameter

const sum = (...numbers) => {
  return numbers.reduce((acc, num) => acc + num, 0)
}

console.log(sum(1, 2, 3, 4)) // 10

7. 배열 Spread

const arr1 = [1, 2]
const arr2 = [...arr1, 3]

console.log(arr2) // [1, 2, 3]

8. 객체 Spread

const user = {
  name: '철수',
  age: 30
}

const newUser = {
  ...user,
  age: 31
}

console.log(newUser) // { name: '철수', age: 31 }

9. map()으로 숫자 변환

const numbers = [1, 2, 3]

const result = numbers.map(num => num * 2)

console.log(result) // [2, 4, 6]

10. map()으로 객체 배열 변환

const users = [
  { name: '철수' },
  { name: '영희' }
]

const result = users.map(user => ({
  ...user,
  active: true
}))

console.log(result) // [{ name: '철수', active: true }, { name: '영희', active: true }]

11. map()으로 특정 속성만 추출

const users = [
  { id: 1, name: '철수' },
  { id: 2, name: '영희' }
]

const names = users.map(user => user.name)

console.log(names) // ['철수', '영희']

12. filter()로 조건에 맞는 값 추출

const numbers = [1, 2, 3, 4, 5]

const result = numbers.filter(num => num >= 3)

console.log(result) // [3, 4, 5]

13. filter()로 객체 배열 삭제

const users = [
  { id: 1, name: '철수' },
  { id: 2, name: '영희' }
]

const result = users.filter(user => user.id !== 1)

console.log(result) // [{ id: 2, name: '영희' }]

14. find()로 객체 하나 찾기

const users = [
  { id: 1, name: '철수' },
  { id: 2, name: '영희' }
]

const user = users.find(user => user.id === 2)

console.log(user) // { id: 2, name: '영희' }

15. findIndex()로 위치 찾기

const users = [
  { id: 10 },
  { id: 20 },
  { id: 30 }
]

const index = users.findIndex(user => user.id === 20)

console.log(index) // 1

16. some()으로 하나라도 존재하는지 확인

const numbers = [1, 3, 5, 8]

const hasEven = numbers.some(num => num % 2 === 0)

console.log(hasEven) // true

17. every()로 모두 만족하는지 확인

const numbers = [10, 20, 30]

const result = numbers.every(num => num >= 10)

console.log(result) // true

18. includes()로 포함 여부 확인

const roles = ['admin', 'user']

console.log(roles.includes('admin')) // true

19. reduce()로 합계 계산

const prices = [1000, 2000, 3000]

const total = prices.reduce(
  (sum, price) => sum + price,
  0
)

console.log(total) // 6000

20. reduce()로 객체 만들기

const users = [
  { id: 1, name: '철수' },
  { id: 2, name: '영희' }
]

const result = users.reduce((acc, user) => {
  acc[user.id] = user
  return acc
}, {})

console.log(result) // { 1: { id: 1, name: '철수' }, 2: { id: 2, name: '영희' } }
2

21~40 불변성 / 객체 처리

21. 배열 뒤에 값 추가

const users = ['철수', '영희']

const result = [...users, '민수']

console.log(result) // ['철수', '영희', '민수']

22. 배열 앞에 값 추가

const users = ['철수', '영희']

const result = ['민수', ...users]

console.log(result) // ['민수', '철수', '영희']

23. 배열에서 특정 값 삭제

const numbers = [1, 2, 3, 4]

const result = numbers.filter(num => num !== 2)

console.log(result) // [1, 3, 4]

24. 배열의 특정 객체 수정

const users = [
  { id: 1, name: '철수' },
  { id: 2, name: '영희' }
]

const result = users.map(user =>
  user.id === 2
    ? { ...user, name: '민지' }
    : user
)

console.log(result) // [{ id: 1, name: '철수' }, { id: 2, name: '민지' }]

25. 객체 복사 후 속성 변경

const user = {
  name: '철수',
  age: 30
}

const result = {
  ...user,
  age: 40
}

console.log(result) // { name: '철수', age: 40 }

26. 중첩 객체 불변성 유지하며 수정

const user = {
  name: '철수',
  profile: {
    age: 30,
    city: '서울'
  }
}

const result = {
  ...user,
  profile: {
    ...user.profile,
    age: 31
  }
}

console.log(result) // { name: '철수', profile: { age: 31, city: '서울' } }

27. 배열 내부 객체의 boolean 토글

const users = [
  { id: 1, active: true }
]

const result = users.map(user =>
  user.id === 1
    ? { ...user, active: !user.active }
    : user
)

console.log(result) // [{ id: 1, active: false }]

28. 여러 ID를 한 번에 삭제

const deleteIds = [1, 3]

const users = [
  { id: 1 },
  { id: 2 },
  { id: 3 },
  { id: 4 }
]

const result = users.filter(
  user => !deleteIds.includes(user.id)
)

console.log(result) // [{ id: 2 }, { id: 4 }]

29. 여러 ID 상태 한 번에 변경

const targetIds = [1, 3]

const users = [
  { id: 1, active: false },
  { id: 2, active: false },
  { id: 3, active: false }
]

const result = users.map(user =>
  targetIds.includes(user.id)
    ? { ...user, active: true }
    : user
)

console.log(result) // [{ id: 1, active: true }, { id: 2, active: false }, { id: 3, active: true }]

30. 객체에서 특정 속성 제외

const user = {
  id: 1,
  name: '철수',
  password: '1234'
}

const { password, ...safeUser } = user

console.log(safeUser) // { id: 1, name: '철수' }

31. 객체 속성 동적 변경 [name]: value

const name = 'age'
const value = 40

const user = {
  name: '철수',
  age: 30
}

const result = {
  ...user,
  [name]: value
}

console.log(result) // { name: '철수', age: 40 }

// React에서 자주 쓰는 형태
setForm(prev => ({
  ...prev,
  [e.target.name]: e.target.value
}))

32. 배열 중복 제거

const numbers = [1, 1, 2, 2, 3]

const result = [...new Set(numbers)]

console.log(result) // [1, 2, 3]

33. 객체 배열 중복 제거

const users = [
  { id: 1, name: '철수' },
  { id: 1, name: '철수' },
  { id: 2, name: '영희' }
]

const result = users.filter(
  (user, index, array) =>
    index === array.findIndex(item => item.id === user.id)
)

console.log(result) // [{ id: 1, name: '철수' }, { id: 2, name: '영희' }]

34. 배열 정렬하면서 원본 유지

const numbers = [3, 1, 2]

const result = [...numbers].sort((a, b) => a - b)

console.log(result) // [1, 2, 3]
console.log(numbers) // [3, 1, 2] (원본 유지)

35. 배열 역순으로 만들면서 원본 유지

const numbers = [1, 2, 3]

const result = [...numbers].reverse()

console.log(result) // [3, 2, 1]

36. 배열 일부 교체

const numbers = [10, 20, 30]

const result = numbers.map(
  (num, index) => index === 1 ? 100 : num
)

console.log(result) // [10, 100, 30]

37. 배열 두 개 합치기

const a = [1, 2]
const b = [3, 4]

const result = [...a, ...b]

console.log(result) // [1, 2, 3, 4]

38. 객체 두 개 합치기

const user = { name: '철수' }
const profile = { age: 30 }

const result = {
  ...user,
  ...profile
}

console.log(result) // { name: '철수', age: 30 }

39. 조건에 따라 객체 속성 추가

const isAdmin = true

const user = {
  name: '철수',
  ...(isAdmin && {
    role: 'admin'
  })
}

console.log(user) // { name: '철수', role: 'admin' }

40. 조건에 따라 배열 항목 추가

const isAdmin = true

const menu = [
  '홈',
  '게시판',
  ...(isAdmin ? ['관리자'] : [])
]

console.log(menu) // ['홈', '게시판', '관리자']
3

41~60 함수 조합 / 고차 함수

41. 함수를 인자로 전달

const calculate = (a, b, callback) => {
  return callback(a, b)
}

const add = (a, b) => a + b

console.log(calculate(10, 20, add)) // 30

42. 함수를 반환하는 함수

const createMultiplier = num => {
  return value => value * num
}

const double = createMultiplier(2)

console.log(double(10)) // 20

43. Callback 함수 사용

const run = callback => {
  callback()
}

run(() => {
  console.log('실행') // '실행' (1회)
})

44. 고차 함수(Higher-Order Function)

const repeat = (count, callback) => {
  for (let i = 0; i < count; i++) {
    callback(i)
  }
}

repeat(3, index => {
  console.log(index) // 0, 1, 2 (순서대로 출력)
})

45. map()에 별도 함수 전달

const double = num => num * 2
const numbers = [1, 2, 3]

const result = numbers.map(double)

console.log(result) // [2, 4, 6]

46. filter()에 별도 조건 함수 전달

const isAdult = user => user.age >= 20

const users = [
  { age: 18 },
  { age: 30 },
  { age: 15 }
]

const result = users.filter(isAdult)

console.log(result) // [{ age: 30 }]

47. sort()에 비교 함수 전달

const ascending = (a, b) => a - b
const numbers = [3, 1, 2]

console.log([...numbers].sort(ascending)) // [1, 2, 3]

48. reduce()에 reducer 함수 전달

const sumReducer = (total, num) => total + num
const numbers = [1, 2, 3]

const total = numbers.reduce(sumReducer, 0)

console.log(total) // 6

49. forEach() 대신 map() 사용

const numbers = [1, 2, 3]

const result = numbers.map(num => num * 10)

console.log(result) // [10, 20, 30]

// 새 배열을 만들 목적이면 map()이 적합

50. 함수 합성(Function Composition)

const add10 = num => num + 10
const double = num => num * 2

const result = double(add10(5))

console.log(result) // 30

51. compose() 구현

const compose =
  (f, g) =>
  value =>
    f(g(value))

const double = n => n * 2
const add10 = n => n + 10

const calculate = compose(double, add10)

console.log(calculate(5)) // 30

52. pipe() 구현

const pipe =
  (...functions) =>
  value =>
    functions.reduce(
      (result, fn) => fn(result),
      value
    )

const add10 = n => n + 10
const double = n => n * 2

const calculate = pipe(add10, double)

console.log(calculate(5)) // 30

53. 여러 변환 함수를 순서대로 실행

const trim = text => text.trim()
const lower = text => text.toLowerCase()
const addPrefix = text => `user_${text}`

const result = addPrefix(
  lower(
    trim(' JOHN ')
  )
)

console.log(result) // user_john

54. 커링(Currying) 기본

const add =
  a =>
  b =>
    a + b

console.log(add(10)(20)) // 30

55. add(10)(20) 형태

const add = a => {
  return b => {
    return a + b
  }
}

const add10 = add(10)

console.log(add10(20)) // 30

56. 조건 함수를 커링으로 만들기

const greaterThan =
  min =>
  value =>
    value > min

const greaterThan10 = greaterThan(10)

console.log(greaterThan10(20)) // true

57. 재사용 가능한 greaterThan()

const greaterThan =
  min =>
  value =>
    value > min

const numbers = [5, 15, 20, 3]

const result = numbers.filter(
  greaterThan(10)
)

console.log(result) // [15, 20]

58. 재사용 가능한 hasProperty()

const hasProperty =
  key =>
  object =>
    key in object

const hasName = hasProperty('name')

console.log(
  hasName({ name: '철수' })
) // true

59. 부분 적용(Partial Application)

const multiply = (a, b) => a * b

const double = b => multiply(2, b)

console.log(double(10)) // 20

60. 함수 Factory 만들기

const createLogger =
  prefix =>
  message => {
    console.log(`[${prefix}]`, message) // '[ERROR] 오류 발생'
  }

const errorLogger = createLogger('ERROR')

errorLogger('오류 발생')
4

61~80 실무 데이터 처리

61. 활성 회원만 추출

const users = [
  { name: '철수', active: true },
  { name: '영희', active: false },
  { name: '민수', active: true }
]

const activeUsers = users.filter(
  user => user.active
)

console.log(activeUsers) // [{ name: '철수', active: true }, { name: '민수', active: true }]

62. 회원 이름만 배열로 변환

const users = [
  { name: '철수' },
  { name: '영희' }
]

const names = users.map(
  user => user.name
)

console.log(names) // ['철수', '영희']

63. 특정 회원 정보 수정

const targetId = 2

const users = [
  { id: 1, name: '철수' },
  { id: 2, name: '영희' }
]

const result = users.map(user =>
  user.id === targetId
    ? { ...user, name: '민지' }
    : user
)

console.log(result) // [{ id: 1, name: '철수' }, { id: 2, name: '민지' }]

64. 특정 회원 삭제

const targetId = 2

const result = users.filter(
  user => user.id !== targetId
)

65. 회원 활성/비활성 토글

const targetId = 1

const result = users.map(user =>
  user.id === targetId
    ? { ...user, active: !user.active }
    : user
)

66. 선택된 ID 목록 만들기

const users = [
  { id: 1, checked: true },
  { id: 2, checked: false },
  { id: 3, checked: true }
]

const ids = users
  .filter(user => user.checked)
  .map(user => user.id)

console.log(ids) // [1, 3]

67. 체크된 항목만 추출

const checkedUsers = users.filter(
  user => user.checked
)

68. 검색어로 목록 필터링

const keyword = '철'

const users = [
  { name: '김철수' },
  { name: '이영희' }
]

const result = users.filter(user =>
  user.name.includes(keyword)
)

console.log(result) // [{ name: '김철수' }]

69. 카테고리별 필터링

const category = 'book'

const products = [
  { name: '책1', category: 'book' },
  { name: '노트북', category: 'pc' }
]

const result = products.filter(
  product => product.category === category
)

70. 가격 범위 필터링

const products = [
  { price: 10000 },
  { price: 30000 },
  { price: 50000 }
]

const result = products.filter(
  product =>
    product.price >= 20000 &&
    product.price <= 40000
)

console.log(result) // [{ price: 30000 }]

71. 이름순 정렬

const users = [
  { name: '민수' },
  { name: '철수' },
  { name: '영희' }
]

const result = [...users].sort(
  (a, b) => a.name.localeCompare(b.name)
)

console.log(result) // [{ name: '민수' }, { name: '영희' }, { name: '철수' }]

72. 가격순 정렬

const products = [
  { price: 5000 },
  { price: 1000 },
  { price: 3000 }
]

const result = [...products].sort(
  (a, b) => a.price - b.price
)

73. 날짜순 정렬

const posts = [
  { date: '2026-09-03' },
  { date: '2026-09-01' }
]

const result = [...posts].sort(
  (a, b) => new Date(b.date) - new Date(a.date)
)

74. 데이터 그룹화

const users = [
  { name: '철수', team: 'A' },
  { name: '영희', team: 'B' },
  { name: '민수', team: 'A' }
]

const grouped = users.reduce((acc, user) => {
  if (!acc[user.team]) {
    acc[user.team] = []
  }

  acc[user.team].push(user)

  return acc
}, {})

console.log(grouped) // { A: [{ name: '철수', team: 'A' }, { name: '민수', team: 'A' }], B: [{ name: '영희', team: 'B' }] }

75. 카테고리별 데이터 그룹화

const products = [
  { name: '책1', category: 'book' },
  { name: '책2', category: 'book' },
  { name: 'PC', category: 'computer' }
]

const grouped = products.reduce((acc, item) => {
  const key = item.category

  acc[key] = acc[key] ?? []
  acc[key].push(item)

  return acc
}, {})

76. 상태별 개수 계산

const tasks = [
  { status: 'done' },
  { status: 'done' },
  { status: 'todo' }
]

const count = tasks.reduce((acc, task) => {
  acc[task.status] =
    (acc[task.status] ?? 0) + 1

  return acc
}, {})

console.log(count)
// { done: 2, todo: 1 }

77. 전체 금액 계산

const products = [
  { price: 1000 },
  { price: 2000 },
  { price: 3000 }
]

const total = products.reduce(
  (sum, product) => sum + product.price,
  0
)

console.log(total) // 6000

78. 선택된 상품 금액 계산

const products = [
  { price: 1000, checked: true },
  { price: 2000, checked: false },
  { price: 3000, checked: true }
]

const total = products
  .filter(item => item.checked)
  .reduce(
    (sum, item) => sum + item.price,
    0
  )

console.log(total) // 4000

79. 장바구니 수량 변경

const targetId = 2

const cart = [
  { id: 1, count: 1 },
  { id: 2, count: 2 }
]

const result = cart.map(item =>
  item.id === targetId
    ? { ...item, count: item.count + 1 }
    : item
)

80. 장바구니 상품 삭제

const targetId = 2

const result = cart.filter(
  item => item.id !== targetId
)
5

81~100 React 함수형 패턴

81. React - setUsers(prev => [...prev, user])

setUsers(prev => [
  ...prev,
  {
    id: 3,
    name: '민수'
  }
])

// prev = 현재 users 상태값

82. React - filter()로 상태에서 삭제

setUsers(prev =>
  prev.filter(
    user => user.id !== targetId
  )
)

83. React - map()으로 상태의 객체 수정

setUsers(prev =>
  prev.map(user =>
    user.id === targetId
      ? {
          ...user,
          name: '홍길동'
        }
      : user
  )
)

84. React - 객체 State 수정

setUser(prev => ({
  ...prev,
  age: 40
}))

85. React - boolean State 토글

setActive(prev => !prev)

86. React - 배열 State에 항목 추가

const [items, setItems] = useState([])

function addItem() {
  setItems(prev => [
    ...prev,
    {
      id: Date.now(),
      name: '새 항목'
    }
  ])
}

87. React - 배열 State에서 항목 삭제

function deleteItem(id) {
  setItems(prev =>
    prev.filter(
      item => item.id !== id
    )
  )
}

88. React - 배열 State의 객체 수정

function updateItem(id) {
  setItems(prev =>
    prev.map(item =>
      item.id === id
        ? { ...item, name: '변경' }
        : item
    )
  )
}

89. React - 체크박스 선택 배열 관리

const [selectedIds, setSelectedIds] = useState([])

function toggle(id) {
  setSelectedIds(prev =>
    prev.includes(id)
      ? prev.filter(item => item !== id)
      : [...prev, id]
  )
}

// 있으면 filter()로 제거
// 없으면 [...prev, id]로 추가

90. React - onChange={setValue} 형태

function Input({ onChange }) {
  return (
    <input
      onChange={e =>
        onChange(e.target.value)
      }
    />
  )
}

// 사용
<Input onChange={setName} />

// 내부적으로 setName(value)가 실행되는 셈

91. React - Optional Callback

function handleChange(value) {
  onChange?.(value)
}

// 아래와 비슷한 의미
if (onChange) {
  onChange(value)
}

92. React - e.target.name으로 객체 변경

const [form, setForm] = useState({
  name: '',
  age: ''
})

function handleChange(e) {
  setForm(prev => ({
    ...prev,
    [e.target.name]: e.target.value
  }))
}

<input name="name" onChange={handleChange} />
<input name="age" onChange={handleChange} />

93. React - items.map()으로 렌더링

const users = [
  { id: 1, name: '철수' },
  { id: 2, name: '영희' }
]

return (
  <ul>
    {users.map(user => (
      <li key={user.id}>
        {user.name}
      </li>
    ))}
  </ul>
)

94. React - filter().map() 조합

return (
  <ul>
    {users
      .filter(user => user.active)
      .map(user => (
        <li key={user.id}>
          {user.name}
        </li>
      ))}
  </ul>
)

// 전체 users → filter → 활성 사용자 → map → li 생성

95. filter → sort → map 체이닝

const result = users
  .filter(user => user.active)
  .toSorted((a, b) => a.age - b.age)
  .map(user => user.name)

// 활성회원만 → 나이순 정렬 → 이름만 추출

96. 조건에 따라 다른 변환 함수 적용

const upper = text => text.toUpperCase()
const lower = text => text.toLowerCase()

const transform =
  type === 'upper'
    ? upper
    : lower

console.log(transform('Hello')) // 'hello' 또는 'HELLO' (type 값에 따라)

97. renderItem 함수를 Props로 전달

function List({
  items,
  renderItem
}) {
  return (
    <ul>
      {items.map(item => (
        <li key={item.id}>
          {renderItem(item)}
        </li>
      ))}
    </ul>
  )
}

<List
  items={users}
  renderItem={user => (
    <strong>{user.name}</strong>
  )}
/>

98. 함수를 Props로 자식에게 전달

function Parent() {
  function handleDelete(id) {
    console.log('삭제', id)
  }

  return (
    <Child onDelete={handleDelete} />
  )
}

function Child({ onDelete }) {
  return (
    <button onClick={() => onDelete(10)}>
      삭제
    </button>
  )
}

99. useMemo()에서 함수형 데이터 가공

const activeUsers = useMemo(() => {
  return users.filter(
    user => user.active
  )
}, [users])

// users가 바뀔 때만 다시 계산
// 단순한 filter에는 무조건 쓸 필요 없음

100. useReducer()로 상태 변경 로직 분리

function reducer(state, action) {
  switch (action.type) {
    case 'ADD':
      return [
        ...state,
        action.user
      ]

    case 'DELETE':
      return state.filter(
        user => user.id !== action.id
      )

    case 'TOGGLE':
      return state.map(user =>
        user.id === action.id
          ? {
              ...user,
              active: !user.active
            }
          : user
      )

    default:
      return state
  }
}

const [users, dispatch] = useReducer(reducer, [])

dispatch({
  type: 'ADD',
  user: {
    id: 1,
    name: '철수',
    active: true
  }
})

dispatch({
  type: 'DELETE',
  id: 1
})

dispatch({
  type: 'TOGGLE',
  id: 1
})

React에서 특히 먼저 익힐 것

전부 외울 필요는 없다. 우선 map, filter, find, some, includes, spread, 삼항연산자, ?., ??, setState(prev => ...), 함수 Props 전달 패턴을 자연스럽게 읽는 게 중요하다.

setUsers(prev =>
  prev
    .filter(user => user.active)
    .map(user =>
      user.id === targetId
        ? {
            ...user,
            name: '홍길동'
          }
        : user
    )
)

한글로 읽으면: 현재 users를 가져온다 → active 사용자만 남긴다 → targetId와 같은 사용자는 복사 후 name만 변경한다 → 나머지는 그대로 둔다 → 새 배열을 상태로 저장한다.