Skip to content

Latest commit

 

History

History
261 lines (221 loc) · 6.86 KB

8.8 반복문을 파이프라인으로 바꾸기.md

File metadata and controls

261 lines (221 loc) · 6.86 KB

8.8 반복문을 파이프라인으로 바꾸기


  • 파이프라인 사용 예시
const names = [];
for (const i of input){
	if(i.job === "programmer")
		names.push(i.name);
}
const names = input
	.filter(i => i.job === "programmer")
	.map(i => i/name);

배경

파이프라인을 사용하면 객체가 파이프라인을 따라 흐르면서 어떻게 처리되는지 읽을 수 있기 때문에 가독성이 더 좋다.

자주 쓰이는 파이프라인

1. map

const numbers = [1, 2, 3, 4, 5];
const result = numbers.map(number => number * number);

console.log(numbers);
// [1, 2, 3, 4, 5];

console.log(result);
// [1, 4, 9, 16, 25]

map은 콜백함수를 이용해서 각 배열 요소에 대해서 연산하고, 새로운 배열을 반환한다.

  • react에서 map을 사용하는 예시
export default function TodoListContainer() {
    const [todoText, setTodoText] = useState([
        {key: 0, text: "컴네 과제 하기",checked: false},
        {key: 1, text: "여주 공연 사회 대본 짜기",checked: true},
        {key: 2, text: "과 종총 날짜 알아보기",checked: false},
    ]);
    const [todoTextInput, setTodoTextInput] = useState('')

    const handleTodoCheck = (e, key) =>{
        setTodoText(todoText.map((item)=>(item.key === key ? {...item, checked: !item.checked} : item)))
    }

    const handleTodoInputChange = (e) =>{
        console.log(e.target.value)
        setTodoTextInput(e.target.value)
    }

    const handleTodoSubmit = (e)=>{
        console.log(e.target.value)
        if(e.key === 'Enter' && e.target.value){
            setTodoText(todoText.concat({key: todoText.length, text: e.target.value, checked: false}))
            setTodoTextInput('')
        }
    }

    return(
        <>
            <ContentArea>
                <PageTitle>Todo List</PageTitle>
                <TextArea
                    placeholder = 'Todo 내용을 입력해주세요'
                    value={todoTextInput}
                    onChange={handleTodoInputChange}
                    onKeyDown={handleTodoSubmit}
                />
                <TodoList
                    todoContentList={todoText}
                    onClick={handleTodoCheck}
                />
            </ContentArea>
        </>
    );
}

2. filter

const words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]

콜백함수의 조건을 만족하는 요소들로 새로운 배열을 구성한다.

절차

리펙터링 전

function acquireData(input){
    const lines = input.split('\n')
    let firstLine = true;
    const result = [];
    for (const line of lines){
        if(firstLine){
            firstLine = false;
            continue;
        }
        if (line.trim() ==="")continue;
        const record = line.split(",");
        if(record[1].trim()==='India'){
            result.push({city: record[0].trim(), phone: record[2].trim()});
        }
    }
    return result;
}

리펙터링 단계

  1. 반복문에서 사용하는 컬렉션을 가리키는 별도 변수를 새로 만든다.
function acquireData(input){
    const lines = input.split('\n')
    let firstLine = true;
    const result = [];
    const loopItems = lines
    for (const line of loopItems){
        if(firstLine){
            firstLine = false;
            continue;
        }
        if (line.trim() ==="")continue;
        const record = line.split(",");
        if(record[1].trim()==='India'){
            result.push({city: record[0].trim(), phone: record[2].trim()});
        }
    }
    return result; 
}
  1. 반복문 안에서 첫 if문은 csv데이터의 첫 줄을 건너뛰는 역할이므로 loop변수에 저장한다.
function acquireData(input){
    const lines = input.split('\n')
    const result = [];
    const loopItems = lines
        .slice(1);
    for (const line of loopItems){
        if (line.trim() === "")continue;
        const record = line.split(",");
        if(record[1].trim()==='India'){
            result.push({city: record[0].trim(), phone: record[2].trim()});
        }
    }
    return result; 
}
  1. line.tirm() 을 사용하는 코드는 빈 줄을 지우는 작업으로 filter()연산으로 대체할 수 있다.
function acquireData(input){
    const lines = input.split('\n')
    const result = [];
    const loopItems = lines
        .slice(1)
        .filter(line => line.trim() !== "");
    for (const line of loopItems){
        const record = line.split(",");
        if(record[1].trim()==='India'){
            result.push({city: record[0].trim(), phone: record[2].trim()});
        }
    }
    return result; 
}
  1. 콤마를 기준으로 split하는 코드는 아래와 같이 map을 사용한 파이프라인으로 대체할 수 있다.
function acquireData(input){
    const lines = input.split('\n')
    const result = [];
    const loopItems = lines
        .slice(1)
        .filter(line => line.trim() !== "")
        .map(line=>line.split(","));
    for (const line of loopItems){
        const record = line;
        if(record[1].trim()==='India'){
            result.push({city: record[0].trim(), phone: record[2].trim()});
        }
    }
    return result; 
}
  1. 다시 한번 fliter연산을 수행하여 인도에 위치한 사무실 레코드만 뽑아낸다.
function acquireData(input){
    const lines = input.split('\n')
    const result = [];
    const loopItems = lines
        .slice(1)
        .filter(line => line.trim() !== "")
        .map(line=>line.split(","))
        .filter(record => record[1].trim() === "India");
    for (const line of loopItems){
        const record = line;
        result.push({city: record[0].trim(), phone: record[2].trim()});
    }
    return result; 
}
  1. 마지막으로 map을 사용해서 결과 레코드를 뽑아낸다
function acquireData(input){
    const lines = input.split('\n')
    const result = [];
    const loopItems = lines
        .slice(1)
        .filter(line => line.trim() !== "")
        .map(line=>line.split(","))
        .filter(record => record[1].trim() === "India")
        .map(record => ({city: record[0].trim(), phone: record[2].trim()}));
    for (const line of loopItems){
        const record = line;
        result.push(line);
    }
    return result; 
}
  1. 모든 반복문 로직을 파이프라인으로 변경했으니 원래 있던 반복문은 제거해준다.
function acquireData(input){
    const lines = input.split('\n')
    const result = lines
        .slice(1)
        .filter(line => line.trim() !== "")
        .map(line=>line.split(","))
        .filter(record => record[1].trim() === "India")
        .map(record => ({city: record[0].trim(), phone: record[2].trim()}));
    return result; 
}