๐๏ธ 09. ๋ฐฐ์ด ๊ณ ์ฐจํจ์ โ mapยทfilterยทreduce๋ฅผ ์ ๋๋ก ์ฐ๋ ์๋์ด์ ์ฌ๊ณ ๋ฒ
๐ ๊ฐ์
map, filter, reduce, find, some, every, flatMap โ ๋งค์ผ ์ฐ๋ ๋ฐฐ์ด ๋ฉ์๋์ ์ฌ๋ฐ๋ฅธ ์ฌ์ฉ๋ฒ๊ณผ ์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ, ํจ์ํ ์กฐํฉ ํจํด.
๐ฏ ์ด ์น์ ์ ์ฝ๊ณ ๋๋ฉด:
map,filter,reduce์ ์ฐจ์ด์ ๊ฐ๊ฐ์ ์ ์ ํ ์ฌ์ฉ ์์ ์ ๋ช ํํ ์๋ค.reduceํ๋๋กmap๊ณผfilter๋ฅผ ๋์์ ์ํํ๋ ์ต์ ํ ํจํด์ ์ดํดํ๋ค.- ๋ถ๋ณ์ฑ์ ์ ์งํ๋ฉด์ ๋ฐฐ์ด์ ์์ ํ๊ฒ ๋ณํํ๋ ํจ์ํ ํจํด์ ์์ฑํ๋ค.
๐ ๋ชฉ์ฐจ
- ๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
- ๐ค 1. ์ ์์์ผ ํ๋๊ฐ?
- ๐ 2. map โ ๋ณํ
- ๐ 3. filter โ ์ ํ
- โ๏ธ 4. reduce โ ์ถ์ฝ
- ๐ 5. find / findIndex / some / every
- ๐ 6. ํจ์ํ ์กฐํฉ ํจํด
- โ ๏ธ 7. ์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ
- ๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
- ๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
- ๐ ๋ ์์๋ณด๊ธฐ
๐ ์ด ๋ฌธ์๋ฅผ ์ฝ๊ธฐ ์ ์
โฑ๏ธ ์์ ์ฝ๊ธฐ ์๊ฐ: 20๋ถ(์ ์ฒด) / ํต์ฌ ํํธ๋ง: 12๋ถ
๐บ๏ธ ์ด ๋ฌธ์์ ํ๋ฆ
[map/filter/reduce ์ฐจ์ด] โ [find/some/every] โ [ํจ์ํ ์กฐํฉ] โ [์ฑ๋ฅ ๊ณ ๋ ค]
๐ฏ ์ด ๋ฌธ์๋ฅผ ๋ค ์ฝ์ผ๋ฉด ํ ์ ์๋ ๊ฒ
- "
reduce๋กmap๊ณผfilter๋ฅผ ํ ๋ฒ์ ํ๋ผ"๋ ๋ง์ ์๋ฏธ์ ๊ตฌํ์ ์๋ค. -
for๋ฃจํ ๋์ ์ ์ ํ ๋ฐฐ์ด ๋ฉ์๋๋ฅผ ์ ํํ๋ค. - ๊ฑฐ๋ํ ๋ฐฐ์ด ์ฒ๋ฆฌ ์ ์ฑ๋ฅ ํธ๋ ์ด๋์คํ๋ฅผ ๊ณ ๋ คํ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
๐บ๏ธ ์ด ๋ฌธ์์ ๋ฐฐ๊ฒฝ ์ธ๊ณ๊ด: '์์๋ค ์ปค๋ฎค๋ํฐ'
๐ฃ ์์ฒ : "์ํธ ๋, ๊ฒ์๊ธ ๋ชฉ๋ก์์ '๊ณต๊ฐ๋ ๊ฒ์๊ธ๋ง ๋ฝ์์, ์ ๋ชฉ๊ณผ ์กฐํ์๋ง ๊ฐ์ง ๊ฐ์ฒด ๋ฐฐ์ด๋ก ๋ง๋ค์ด์, ์กฐํ์ ๊ธฐ์ค์ผ๋ก ์ ๋ ฌ'ํ๋ ์ฝ๋๋ฅผ ์งฐ๋๋ฐ์...
filterํ ๋ฒ,mapํ ๋ฒ,sortํ ๋ฒ ๋๋ฆฌ๋๊น ๋ฐฐ์ด์ ์ธ ๋ฒ ์ํํ๋๋ผ๊ณ ์. ์ด๊ฑฐ ์ข ๋๋ฆฐ ๊ฑฐ ์๋๊ฐ์?"
๐ฆ ์ํธ: "๋ ์นด๋กญ๊ฒ ์ ๋ดค์ด. ๋ฐฐ์ด ๋ฉ์๋๋ฅผ ์ฒด์ด๋ํ๋ฉด ๊ฐ ๋จ๊ณ๋ง๋ค ์ ๋ฐฐ์ด์ด ๋ง๋ค์ด์ง๊ณ ์ํ๊ฐ ์ผ์ด๋. ๋ฐ์ดํฐ๊ฐ ์๋์ด๋ฉด ๊ด์ฐฎ์ง๋ง, ๋์ฉ๋์ด๋ผ๋ฉด
reduceํ๋๋กfilter + map์ ํ ๋ฒ์ ์ํ์ ์ฒ๋ฆฌํ๋ ๊ฒ ํจ์จ์ ์ด์ผ. ์ค๋ ๋ฐฐ์ด ๊ณ ์ฐจํจ์๋ฅผ ์ ๋๋ก ๋ฐฐ์ฐ๋ฉด ์ธ์ ์ด๋ค ๋ฉ์๋๋ฅผ ์ธ์ง ํ๋จ์ด ์๊ฒ ๋ผ."
๐ค 1. ์ ์์์ผ ํ๋๊ฐ?
๋ฐฐ์ด ๊ณ ์ฐจํจ์๋ React ๊ฐ๋ฐ์์ ๋งค์ผ ์ฌ์ฉ๋๋ค:
- ์๋ฒ ๋ฐ์ดํฐ โ JSX ๋ณํ:
map - ์กฐ๊ฑด ํํฐ๋ง:
filter - ์ง๊ณ/๋ณํ:
reduce - ํด๋ฆญํ ํญ๋ชฉ ์ฐพ๊ธฐ:
find - ์ ํจ์ฑ ๊ฒ์ฌ:
some,every
for ๋ฃจํ๋ณด๋ค ์๋๊ฐ ๋ช ํ ํ๊ณ , ๋ถ๋ณ์ฑ์ ์ ์ง ํ๊ธฐ ์ฝ๋ค. ๋จ, ์๋ชป ์ฐ๋ฉด ๋ถํ์ํ ์ํ๊ฐ ๋ฐ์ํ๋ค.
๐ 2. map โ ๋ณํ
์ํธ ๋ฆฌ๋ ๋์ด ์์ฒ ์ด์ PR์ "์ฌ๊ธด map์ ์ฐ๋ฉด ๋ ๊น๋ํ ๊ฒ ๊ฐ์์"๋ผ๊ณ ๋จ๊ธฐ์
จ๋ ๊ทธ ๋ฉ์๋์
๋๋ค. ์๋ณธ ๋ฐฐ์ด๊ณผ ๊ฐ์ ๊ธธ์ด์ ์ ๋ฐฐ์ด์ ๋ฐํํ๋ฉฐ, ๊ฐ ์์๋ฅผ ์ํ๋ ํํ๋ก ๋ณํํ ๋ ์ ๋ฒ์
๋๋ค.
const posts = [
{ id: 1, title: "ํด๋ก์ ", viewCount: 1234, isPublished: true },
{ id: 2, title: "this ๋ฐ์ธ๋ฉ", viewCount: 567, isPublished: false },
{ id: 3, title: "Promise", viewCount: 890, isPublished: true },
];
// โ ์์งํ ์ฝ๋ โ ๋ช
์์ for ๋ฃจํ + ์ ๋ฐฐ์ด
const titles = [];
for (const post of posts) {
titles.push(post.title);
}
// โ
map โ ์๋ ๋ช
ํ, ํ ์ค
const titles = posts.map((post) => post.title);
// ["ํด๋ก์ ", "this ๋ฐ์ธ๋ฉ", "Promise"]
// ๊ฐ์ฒด ๋ณํ (DTO ํจํด)
const postSummaries = posts.map(({ id, title, viewCount }) => ({
id,
title,
viewCount,
// ์๋ฒ ์๋ต ๊ทธ๋๋ก ๋
ธ์ถํ์ง ์๊ณ ํ๋ก ํธ ์ ์ฉ ํํ๋ก ๋ณํ
formattedViews: viewCount.toLocaleString(),
}));
// React์์์ ์ฌ์ฉ
const PostList = ({ posts }) => (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li> // key ํ์!
))}
</ul>
);map ์ฌ์ฉ ๊ธฐ์ค: ๋ฐฐ์ด์ ๋ชจ๋ ์์๋ฅผ ๋ณํํด์ผ ํ ๋. ์์๋ฅผ ์ ๊ฑฐํ๊ฑฐ๋ ๊ฐ์๋ฅผ ๋ฐ๊พธ๋ฉด ์ ๋จ.
๐ 3. filter โ ์ ํ
์กฐ๊ฑด์ ๋ง๋ ์์๋ง ์์ ๊ณจ๋ผ ๋ด์ ์ ๋ฐฐ์ด์ ๋ฐํํฉ๋๋ค. ๊ฒฐ๊ณผ๋ฌผ์ ์๋ณธ๋ณด๋ค ์งง๊ฑฐ๋ ๊ฐ์ ์๋ฐ์ ์๊ฒ ์ฃ ?
// ๊ณต๊ฐ๋ ๊ฒ์๊ธ๋ง
const publishedPosts = posts.filter((post) => post.isPublished);
// [{ id: 1, ...}, { id: 3, ...}]
// ์กฐํ์ 500 ์ด์์ธ ๊ฒ์๊ธ
const popularPosts = posts.filter((post) => post.viewCount >= 500);
// ๋ณตํฉ ์กฐ๊ฑด
const featuredPosts = posts.filter(
(post) => post.isPublished && post.viewCount >= 1000
);
// ์ค๋ณต ์ ๊ฑฐ (์์๊ฐ)
const tags = ["js", "react", "js", "css", "react"];
const uniqueTags = tags.filter((tag, index) => tags.indexOf(tag) === index);
// ["js", "react", "css"]
// ๋ ํ๋์ : Set์ผ๋ก ์ค๋ณต ์ ๊ฑฐ
const uniqueTags2 = [...new Set(tags)];โ๏ธ 4. reduce โ ์ถ์ฝ
์คํ๋์์ ์์ฒ ์ด๊ฐ "๋ฐฐ์ด์ ์ฌ๋ฌ ๋ฒ ์ํํ๋ฉด ๋๋ฆฌ์ง ์์๊น์?"๋ผ๊ณ ๊ฑฑ์ ํ๋ ๋ถ๋ถ์ ํด๋ต์ ๋๋ค. ์ฌ๋ฌ ๊ฐ์ ์์๋ฅผ ํ๋์ ๊ฐ์ผ๋ก ์์ถํ ๋ ์ฌ์ฉํฉ๋๋ค. ํ์ฉ๋๊ฐ ๋ฌด๊ถ๋ฌด์งํ์ง๋ง, ๊ทธ๋งํผ ์ ์คํ๊ฒ ์จ์ผ ํ๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ฃ .
// ๊ธฐ๋ณธ ํํ: reduce(callback, initialValue)
// callback(accumulator, currentValue, index, array) โ nextAccumulator
// ํฉ๊ณ
const totalViews = posts.reduce((sum, post) => sum + post.viewCount, 0);
// 1234 + 567 + 890 = 2691
// ๊ฐ์ฒด ๊ทธ๋ฃนํ (๋งค์ฐ ์์ฃผ ์ฐ์ด๋ ํจํด)
const users = [
{ id: 1, name: "์์ฒ ", role: "junior" },
{ id: 2, name: "์ํธ", role: "lead" },
{ id: 3, name: "์์", role: "lead" },
{ id: 4, name: "์์", role: "designer" },
];
const byRole = users.reduce((groups, user) => {
const { role } = user;
return {
...groups,
[role]: [...(groups[role] ?? []), user],
};
}, {});
// {
// junior: [{ id: 1, name: "์์ฒ ", ... }],
// lead: [{ id: 2, ... }, { id: 3, ... }],
// designer: [{ id: 4, ... }]
// }
// ID๋ฅผ ํค๋ก ํ๋ Map ์์ฑ (O(1) ์กฐํ์ฉ)
const postsById = posts.reduce((map, post) => {
map[post.id] = post;
return map;
}, {});
postsById[1]; // { id: 1, title: "ํด๋ก์ ", ... } โ O(1)!reduce๋ก filter + map์ ํ ๋ฒ์ ์ํ์:
๋ถํ์ํ๊ฒ ๋ฐฐ์ด์ ๋ ๋ฒ ๋ง๋๋ ๋์ , ํ ๋ฒ์ ๊ฐ์์ง๊ณผ ํ ๋ฒ์ ๋ฐ๋์ง๋ก ๋๋ผ ์ ์์ต๋๋ค. ์ํธ ๋ฆฌ๋ ๋์ด ๋์ฉ๋ ๋ฐ์ดํฐ ์ฒ๋ฆฌ๋ฅผ ์ํด ์๋ ค์ค ์ต์ ํ ๊ธฐ๋ฒ์ ๋๋ค.
// โ filter + map โ ๋ ๋ฒ ์ํ (๊ฐ๊ฐ ์ ๋ฐฐ์ด ์์ฑ)
const result = posts
.filter((post) => post.isPublished)
.map(({ id, title, viewCount }) => ({ id, title, viewCount }));
// โ
reduce ํ๋๋ก โ ํ ๋ฒ ์ํ, ๋ฐฐ์ด ํ๋๋ง ์์ฑ
const result = posts.reduce((acc, post) => {
if (!post.isPublished) return acc; // filter ์ญํ
acc.push({ id: post.id, title: post.title, viewCount: post.viewCount }); // map ์ญํ
return acc;
}, []);
// ์ฃผ์: ์๋ ๋ฐ์ดํฐ์์๋ filter + map์ด ๋ ๊ฐ๋
์ฑ์ด ์ข๋ค.
// reduce ์ต์ ํ๋ ๋ฐฐ์ด์ด ์ถฉ๋ถํ ํด ๋ ์๋ฏธ ์๋ค.๐ 5. find / findIndex / some / every
์ํ๋ ๋จ ํ๋๋ฅผ ์ฐพ๊ฑฐ๋, ์ํ๋ฅผ ๋น ๋ฅด๊ฒ ํ์ธํ ๋ ์ ์ฉํ ๋ฉ์๋๋ค์ ๋๋ค.
const posts = [
{ id: 1, title: "ํด๋ก์ ", isPublished: true },
{ id: 2, title: "Promise", isPublished: false },
{ id: 3, title: "async/await", isPublished: true },
];
// find โ ์กฐ๊ฑด์ ๋ง๋ ์ฒซ ๋ฒ์งธ ์์ ๋ฐํ (์์ผ๋ฉด undefined)
const foundPost = posts.find((p) => p.id === 2);
// { id: 2, title: "Promise", isPublished: false }
// ์ฐพ์๋ง์ ์ํ ์ค๋จ โ filter๋ณด๋ค ํจ์จ์ (ํ๋๋ง ์ฐพ์ ๋)
// findIndex โ ์ธ๋ฑ์ค ๋ฐํ (์์ผ๋ฉด -1)
const index = posts.findIndex((p) => p.id === 2); // 1
// ๋ฐฐ์ด์์ ํน์ ํญ๋ชฉ ๊ต์ฒด/์ญ์ ์ ์ ์ฉ
// ๋ฐฐ์ด์์ ํญ๋ชฉ ๊ต์ฒด ํจํด (๋ถ๋ณ)
const togglePublish = (posts, targetId) =>
posts.map((p) =>
p.id === targetId ? { ...p, isPublished: !p.isPublished } : p
);
// some โ ํ๋๋ผ๋ ์กฐ๊ฑด ์ถฉ์กฑํ๋ฉด true (๋จ๋ฝ ํ๊ฐ)
const hasUnpublished = posts.some((p) => !p.isPublished); // true
// ์ฐพ์๋ง์ true ๋ฐํ โ ์ ์ฒด ์ํ ์ ํจ
// every โ ๋ชจ๋ ์กฐ๊ฑด ์ถฉ์กฑํ๋ฉด true
const allPublished = posts.every((p) => p.isPublished); // false
// ์คํจํ์๋ง์ false ๋ฐํ โ ์ ์ฒด ์ํ ์ ํจ
// includes โ ์์๊ฐ ํฌํจ ์ฌ๋ถ
const tags = ["js", "react", "css"];
tags.includes("react"); // true (find๋ณด๋ค ๊ฐ๋จ)๐ 6. ํจ์ํ ์กฐํฉ ํจํด
์ค์ ์์๋ค ์ปค๋ฎค๋ํฐ์์ ๊ฒ์๊ธ ๋ชฉ๋ก์ ํํฐ๋งํ๊ณ ์ ๋ ฌํ๊ณ ํ์ด์ง๋ค์ด์ ํ๋ '๋ฐ์ดํฐ ํ์ดํ๋ผ์ธ'์ ์ด๋ป๊ฒ ๊ตฌ์ฑํ๋์ง ์ดํด๋ณด๊ฒ ์ต๋๋ค.
// ์์๋ค ์ปค๋ฎค๋ํฐ โ ๊ฒ์๊ธ ๋ชฉ๋ก ํํฐ๋ง/์ ๋ ฌ/ํ์ด์ง๋ค์ด์
ํ์ดํ๋ผ์ธ
const getPaginatedPosts = ({
posts,
category,
minViews = 0,
sortBy = "viewCount",
page = 1,
pageSize = 10,
}) => {
return posts
.filter((p) => !category || p.category === category) // ์นดํ
๊ณ ๋ฆฌ ํํฐ
.filter((p) => p.isPublished && p.viewCount >= minViews) // ๊ณต๊ฐ + ์กฐํ์ ํํฐ
.sort((a, b) => b[sortBy] - a[sortBy]) // ์ ๋ ฌ (๋ด๋ฆผ์ฐจ์)
.slice((page - 1) * pageSize, page * pageSize); // ํ์ด์ง๋ค์ด์
};
// ์ฌ์ฉ
const result = getPaginatedPosts({
posts: allPosts,
category: "javascript",
minViews: 100,
sortBy: "viewCount",
page: 2,
pageSize: 10,
});
// ํจ์ํ ํ์ดํ๋ผ์ธ โ compose/pipe ํจํด
const pipe =
(...fns) =>
(value) =>
fns.reduce((acc, fn) => fn(acc), value);
const processUsers = pipe(
(users) => users.filter((u) => u.isActive),
(users) => users.map((u) => ({ ...u, displayName: `${u.name} (${u.role})` })),
(users) => users.sort((a, b) => a.name.localeCompare(b.name))
);โ ๏ธ 7. ์ฑ๋ฅ ๊ณ ๋ ค์ฌํญ
์ํธ ๋ฆฌ๋ ๋์ด ์์ฒ ์ด์ ์ฝ๋์์ ๋ฐ๊ฒฌํ ์ฑ๋ฅ ํจ์ ์
๋๋ค. "์์ฒ ๋, ๋ฃจํ ์์์ find๋ฅผ ๊ณ์ ํธ์ถํ๋ฉด ๋ฐ์ดํฐ๊ฐ ๋ง์์ง ๋ ๋ธ๋ผ์ฐ์ ๊ฐ ํ๋ค์ดํด์. ๋ฏธ๋ฆฌ ์ง๋๋ฅผ ๋ง๋ค์ด๋๋ ๊ฒ ์ข๊ฒ ์ฃ ?"
// โ ๋ฃจํ ์์์ ๋ฐฐ์ด ๋ฉ์๋ ์ค๋ณต ํธ์ถ
const isValidComment = (commentId) => {
// posts.find๋ฅผ comment๋ง๋ค ํธ์ถ โ O(n * m)
const post = posts.find((p) => p.comments.includes(commentId));
return !!post;
};
// โ
๋จผ์ Set์ผ๋ก ๋ณํ โ O(1) ์กฐํ
const commentIdSet = new Set(
posts.flatMap((p) => p.comments)
);
const isValidComment = (commentId) => commentIdSet.has(commentId); // O(1)
// flatMap โ map + flat(1) ๊ฒฐํฉ
const nestedTags = [
{ title: "React ๊ธฐ์ด", tags: ["react", "js"] },
{ title: "Next.js ์ฌํ", tags: ["nextjs", "react", "ssr"] },
];
// โ map + flat
const allTags = nestedTags.map((p) => p.tags).flat();
// โ
flatMap โ ํ ๋ฒ์
const allTags = nestedTags.flatMap((p) => p.tags);
// ["react", "js", "nextjs", "react", "ssr"]
// sort์ ๋ถ๋ณ์ฑ ์ฃผ์
const posts = [{ id: 3 }, { id: 1 }, { id: 2 }];
// โ sort๋ ์๋ณธ ๋ฐฐ์ด์ ๋ณ๊ฒฝํจ!
const sorted = posts.sort((a, b) => a.id - b.id); // posts๋ ๋ณ๊ฒฝ๋จ!
// โ
๋ณต์ฌ ํ ์ ๋ ฌ
const sorted = [...posts].sort((a, b) => a.id - b.id);
// ๋๋ (ES2023)
const sorted = posts.toSorted((a, b) => a.id - b.id); // ์๋ณธ ๋ถ๋ณ ์ ๋ฉ์๋๐ ๋ง๋ฌด๋ฆฌ ํด์ฆ
Q1. find์ filter์ ์ฐจ์ด๋ฅผ ์ค๋ช
ํ๊ณ , ๊ฐ๊ฐ ์ธ์ ์จ์ผ ํ๋๊ฐ?
โ ์ ๋ต:
filter: ์กฐ๊ฑด์ ๋ง๋ ๋ชจ๋ ์์๋ฅผ ์ ๋ฐฐ์ด ๋ก ๋ฐํ (ํญ์ ๋ฐฐ์ด ๋ฐํ)find: ์กฐ๊ฑด์ ๋ง๋ ์ฒซ ๋ฒ์งธ ์์ ๋ฅผ ๋ฐํ, ์์ผ๋ฉดundefined(๋ฐฐ์ด ์๋)
๐ก ์์ธ ํด์ค:
filter๋ "์กฐ๊ฑด์ ๋ง๋ ๊ฒ์๊ธ ๋ชฉ๋ก ์ ์ฒด" โ ๊ฒฐ๊ณผ๊ฐ ์ฌ๋ฌ ๊ฐ์ผ ๋find๋ "ID๊ฐ 42์ธ ๊ฒ์๊ธ" โ ๊ฒฐ๊ณผ๊ฐ ํ๋์ผ ๋ (๋ ํจ์จ์ , ์ฐพ์๋ง์ ์ค๋จ)find๋ก ์ฐพ์ ๊ฒฐ๊ณผ๋null์ฒดํฌ๋ฅผ ํด์ผ ํ๋ค:const post = posts.find(...); if (post) { ... }- ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: "filter๋ '์ ๋ถ ๋ค', find๋ '๋ฑ ํ๋'. ํ๋๋ง ์ฐพ์ ๊ฑฐ๋ผ๋ฉด find๊ฐ ๋น ๋ฅด๋ค."
Q2. ์๋ reduce ์ฝ๋๊ฐ ํ๋ ์ผ์ ์ค๋ช
ํ๊ณ , ๋ ์ฝ๊ธฐ ์ฌ์ด ์ฝ๋๋ก ๋ฆฌํฉํ ๋งํ๋ผ.
const result = posts.reduce((acc, p) => ({
...acc,
total: acc.total + 1,
views: acc.views + p.viewCount,
published: acc.published + (p.isPublished ? 1 : 0),
}), { total: 0, views: 0, published: 0 });โ ์ ๋ต: ๊ฒ์๊ธ ๋ชฉ๋ก์ ์ด ๊ฐ์, ์ด ์กฐํ์, ๊ณต๊ฐ ๊ฒ์๊ธ ์๋ฅผ ํ ๋ฒ์ ์ํ๋ก ์ง๊ณํ๋ค.
๐ก ์์ธ ํด์ค:
- ์ด ์ฝ๋๋
total,views,published์ธ ๊ฐ์ง ๊ฐ์ ๋์์ ์ง๊ณํ๋reduceํจํด์ด๋ค. - ๋ฆฌํฉํ ๋ง ๋ฐฉํฅ:
// ๊ฐ๊ฐ ๋ณ๋๋ก ๊ณ์ฐ (๊ฐ๋ ์ฑ ์ฐ์ , ์๋ ๋ฐ์ดํฐ) const total = posts.length; const views = posts.reduce((sum, p) => sum + p.viewCount, 0); const published = posts.filter((p) => p.isPublished).length; // ๋๋ ๋ช ์์ ๋ณ์๋ช ์ผ๋ก reduce ์ ์ง (๋์ฉ๋ ๋ฐ์ดํฐ) const stats = posts.reduce( (acc, post) => { acc.total++; acc.views += post.viewCount; if (post.isPublished) acc.published++; return acc; }, { total: 0, views: 0, published: 0 } ); - ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: "
reduce๋ ๋ง๋ฅ์ด์ง๋ง, ๊ฐ๋ ์ฑ์ ๋จผ์ ์ฑ๊ฒจ๋ผ. ๋ฐ์ดํฐ๊ฐ ํฌ์ง ์์ผ๋ฉด ๊ฐ๊ฐ ๊ณ์ฐํ๋ ๊ฒ ๋ ์ฝ๊ธฐ ์ฝ๋ค."
Q3. ์์ฒ ์ด์ ํ ์คํธ ํ์ โ ์ค๋ฌด ๋๋ ๋ง
์ํธ ๋ฆฌ๋๊ฐ ์ฝ๋๋ฆฌ๋ทฐ์์ ๋ฌป๋๋ค: "์์ฒ ๋,
.sort()๋ฅผ ๊ทธ๋ฅ ์ฐ๋ฉด ์๋ณธ ๋ฐฐ์ด์ด ๋ณ๊ฒฝ๋ผ์. React state์์ ์ด๊ฑธ ์ฐ๋ฉด ์ด๋ค ๋ฌธ์ ๊ฐ ์๊ธฐ์ฃ ?"
โ
์ ๋ต: sort()๋ ์๋ณธ ๋ฐฐ์ด์ ๋ณ๊ฒฝ(mutation)ํ๋ค. React state ์ง์ ๋ณ๊ฒฝ์ ๋ฆฌ๋ ๋ ๊ฐ์ง๊ฐ ์ ๋๊ณ ์์ธก ๋ถ๊ฐ๋ฅํ ๋ฒ๊ทธ๋ฅผ ๋ง๋ ๋ค. ๋ณต์ฌ ํ ์ ๋ ฌํ๊ฑฐ๋ toSorted()๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
๐ก ์์ธ ํด์ค:
// โ React state ์ง์ ๋ณ๊ฒฝ โ ๋ฆฌ๋ ๋ ์ ๋จ!
const [posts, setPosts] = useState([...]);
const handleSort = () => {
posts.sort((a, b) => a.viewCount - b.viewCount); // ์๋ณธ ์ง์ ๋ณ๊ฒฝ
setPosts(posts); // ๋์ผํ ๋ฐฐ์ด ์ฐธ์กฐ โ React๊ฐ ๋ณ๊ฒฝ์ ๊ฐ์ง ๋ชปํจ
};
// โ
๋ณต์ฌ ํ ์ ๋ ฌ โ ์ ๋ฐฐ์ด ์ฐธ์กฐ
const handleSort = () => {
const sorted = [...posts].sort((a, b) => a.viewCount - b.viewCount);
setPosts(sorted); // ์ ๋ฐฐ์ด ์ฐธ์กฐ โ ๋ฆฌ๋ ๋ ๋ฐ์
};
// โ
ES2023 toSorted โ ์๋ณธ ๋ถ๋ณ ์ ๋ฉ์๋
const handleSort = () => {
setPosts(posts.toSorted((a, b) => a.viewCount - b.viewCount));
};- ๋ง์ฐฌ๊ฐ์ง๋ก
push,splice,reverse๋ ์๋ณธ ๋ณ๊ฒฝ โ React state์์ ๊ธ์ง. - ๋์
[...arr, newItem],arr.filter(...),[...arr].reverse()๋๋arr.toReversed()๋ฅผ ์ฌ์ฉ. - ๐ ํต์ฌ ๊ธฐ์ต๋ฒ: "React state๋ ๋ถ๋ณ์ด์ด์ผ ํ๋ค. ๋ฐฐ์ด ๋ฉ์๋ ์ค ์๋ณธ์ ๋ณ๊ฒฝํ๋ ๊ฒ๋ค(sort, push, splice, reverse)์ state์์ ์ ๋ ์ง์ ์ฌ์ฉ ๊ธ์ง."
๐ฃ ์์ฒ ์ด์ ํด๊ทผ ์ผ๊ธฐ
๋ฐฐ์ด ๊ณ ์ฐจํจ์๋ ๋งค์ผ ์ฐ๋ ๊ฑด๋ฐ ์ค๋ ๋ ๋ฐฐ์ธ ๊ฒ ์์๋ค. sort()๊ฐ ์๋ณธ์ ๋ฐ๊พผ๋ค๋ ๊ฑด ์๊ณ ์์๋๋ฐ, React state์์ ๊ทธ๊ฒ ์ ์น๋ช
์ ์ธ์ง ์ด์ ๋ช
ํํ๊ฒ ์ค๋ช
ํ ์ ์๊ฒ ๋๋ค.
reduce๋ก filter + map์ ๋์์ ํ๋ ํจํด๋ ์ฌ๋ฏธ์์๋ค. ๊ทผ๋ฐ ์ํธ ๋์ด "๊ฐ๋
์ฑ์ด ๋ ์ค์ํ๋ค, ๋์ฉ๋ ์๋๋ฉด ๊ฐ๊ฐ ์ฐ๋ผ"๊ณ ํ๋๋ฐ โ ๊ทธ ๊ท ํ๊ฐ์ด ์ง์ง ์๋์ด์ ํ๋จ์ธ ๊ฒ ๊ฐ๋ค. ๋๋ ๋ฌด์กฐ๊ฑด ์ต์ ํ๊ฐ ์ข์ ์ค ์์๋๋ฐ.
๐ก ์ค๋์ ๊ตํ: "๋ฐฐ์ด ๊ณ ์ฐจํจ์๋ ์๋๋ฅผ ์ฝ๋์ ์๊ธฐ๋ ๋๊ตฌ๋ค.
map์ '์ ๋ถ ๋ณํ',filter๋ '์กฐ๊ฑด์ผ๋ก ์ ํ',reduce๋ 'ํ๋๋ก ์ถ์ฝ'. ์๋์ ๋ง๋ ๋ฉ์๋๋ฅผ ์ฐ๋ฉด ์ฝ๋๊ฐ ์์ฐ์ด์ฒ๋ผ ์ฝํ๋ค."
์ค๋ ํด๊ทผํ๋ฉด์ ์ํธ ๋์ด "๋ค์์ ๋ชจ๋ ์์คํ ์ด์ผ"๋ผ๊ณ ํ๋๋ฐ, ESM์ด๋ CJS ์ฐจ์ด๊ฐ ๋ญ์ง ์ด๋ ดํ์ด๋ ์์ง๋ง ์ ๋๋ก๋ ๋ชจ๋ฅธ๋ค. ๊ธ์์ผ์ด๋๊น ์ฃผ๋ง์ ํ ๋ฒ ๋ ์ฝ์ด๋ด์ผ์ง. ์ค๋ ํ๋ฃจ๋ ์๊ณ ํ๋ค!