해결과제
1. 같은 선박의 항해 기록은 하나로 합치고, 총 운항 거리와 사용된 연료량을 누적한다.
2. 각 선박의 연료 효율(km/L)을 계산한다. (distance/fuelUsed) => 소수점 2자리 각 객체의 새로운 key 값 efficiency를 추가하여 효율 값을 지정 한다.
3. 선박들을 연료 효율(km/L) 기준으로 내림차순 정렬한다.
4. 최종 결과를 반환한다. : {ships : [정리된 선박 배열], totalFuelUsed : 최종 연료 사용}
기본코드
function analyzeShipFuelUsage(voyageRecords) {
}
const voyageRecords = [
{ shipId: 1, shipName: "POSSM", distance: 1000, fuelUse: 200 },
{ shipId: 2, shipName: "폴라리스", distance: 1500, fuelUse: 280 },
{ shipId: 1, shipName: "POSSM", distance: 800, fuelUse: 160 },
{ shipId: 3, shipName: "시도상선", distance: 2000, fuelUse: 400 },
];
console.log(analyzeShipFuelUsage(voyageRecords));
문제 해결 과정
- 같은 선박의 항해 기록은 하나로 합치고, 총 운항 거리와 사용된 연료량을 누적한다.
먼저 이 문제의 해결 과제를 두 가지로 나누었다.
1. 같은 shipId를 가진 선박을 하나로 합치기
• 먼저, 새로운 객체를 생성하고, 기존 항해 기록을 순회하면서 shipId가 새로운 객체에 이미 존재하는지 확인한다.
• 만약 shipId가 없다면, 새로운 객체에 shipId를 키로 하여 새로운 데이터를 추가한다.
2. 연료 사용량과 거리 누적값 계산
• 만약 이미 shipId가 존재하면, 해당 선박의 운항 거리(distance)와 연료 사용량(fuelUse)을 누적한다.
function totalShipData(voyageRecords) {
let shipMap = {}; // 각 shipId를 키로 하고, 선박 데이터를 저장하는 객체
// 배열을 순회하여 각 선박의 항해 기록을 처리
voyageRecords.forEach((record) => {
// shipId가 존재하지 않으면 새로운 선박 데이터를 객체에 추가
if (!shipMap[record.shipId]) {
shipMap[record.shipId] = {
shipId: record.shipId, // 선박의 ID
shipName: record.shipName, // 선박의 이름
distance: 0, // 초기 운항 거리 값 (누적할 값)
fuelUse: 0, // 초기 연료 사용량 값 (누적할 값)
};
}
// 이미 존재하는 shipId에 대해 운항 거리와 연료 사용량을 누적
shipMap[record.shipId].distance += record.distance;
shipMap[record.shipId].fuelUse += record.fuelUse;
});
return shipMap; // 최종적으로 shipId를 키로 한 누적된 선박 데이터를 반환
}
- 각 선박의 연료 효율(km/L)을 계산한다. (distance/fuelUsed) => 소수점 2자리 각 객체의 새로운 key 값 efficiency를 추가하여 효율 값을 지정 한다.
연료 효율을 계산하고 객체의 새로운 속성으로 추가하기 위해서 .map()을 사용하려고 했다. 하지만 map은 배열에서만 사용 가능 하므로 기존에 객체였던 shipMap을 배열로 변환해주는 작업을 추가했다.
function arrayShips(shipMap) {
// Object.values(shipMap)은 shipMap 객체에서 값들만 추출해서 배열로 변환
const shipArray = object.values(shipMap).map((ship) => {
ship.efficiency = (ship.distance / ship.fuelUse).toFixed(2);
return ship;
});
return shipArray;
}
// shipArray 리턴값 결과
[
{
"shipId": 2,
"shipName": "폴라리스",
"distance": 1500,
"fuelUse": 280,
"efficiency": "5.36"
},
{
"shipId": 1,
"shipName": "POSSM",
"distance": 1800,
"fuelUse": 360,
"efficiency": "5.00"
},
{
"shipId": 3,
"shipName": "시도상선",
"distance": 2000,
"fuelUse": 400,
"efficiency": "5.00"
}
]
- 선박들을 연료 효율(km/L) 기준으로 내림차순 정렬한다.
sort() 메서드는 배열을 정렬할 때 사용되며, 매개변수로 전달된 비교 함수를 사용하여 배열의 요소를 정렬한다.
여기서 매개변수로 전달 된 a,b는 배열의 두 요소를 나타낸다.
function sortShipsByEfficiency(shipData) {
return shipData.sort((a,b) => b.efficiency - a.efficiency);
}
- 최종 결과를 반환한다. : {ships : [정리된 선박 배열], totalFuelUsed : 최종 연료 사용}
function analyzeShipFuelUsage(voyageRecords) {
const shipData = totalShipData(voyageRecords); // 1
const efficiencyShips = arrayShips(shipData); // 2
const sortedShips = sortShipsByEfficiency(efficiencyShips); // 3
// 전체 연료 사용량 계산
const totalFuelUsed = efficiencyShips.reduce(
(sum, ship) => sum + ship.fuelUse,
0
);
return { ships: sortedShips, totalFuelUsed: totalFuelUsed };
}
최종 결과
// ------------------- 전체 코드 -------------------
function analyzeShipFuelUsage(voyageRecords) {
const shipData = totalShipData(voyageRecords); // 1단계: 데이터 합치기
const efficiencyShips = arrayShips(shipData);
const sortedShips = sortShipsByEfficiency(efficiencyShips); // 3단계: 연료 효율 기준으로 정렬
// 전체 연료 사용량 계산
const totalFuelUsed = efficiencyShips.reduce(
(sum, ship) => sum + ship.fuelUse,
0
);
return { ships: sortedShips, totalFuelUsed: totalFuelUsed };
}
function totalShipData(voyageRecords) {
const shipMap = {};
// 같은 선박을 합치고 연료 사용량과 거리를 누적
voyageRecords.forEach((record) => {
if (!shipMap[record.shipId]) {
shipMap[record.shipId] = {
shipId: record.shipId,
shipName: record.shipName,
distance: 0,
fuelUse: 0,
};
}
shipMap[record.shipId].distance += record.distance;
shipMap[record.shipId].fuelUse += record.fuelUse;
});
return shipMap;
}
function arrayShips(shipMap) {
// 연료 효율을 계산하고, 배열로 변환
const shipArray = Object.values(shipMap).map((ship) => {
ship.efficiency = (ship.distance / ship.fuelUse).toFixed(2);
return ship;
});
return shipArray;
}
function sortShipsByEfficiency(shipData) {
// 연료 효율을 기준으로 내림차순 정렬
return shipData.sort((a, b) => b.efficiency - a.efficiency);
}
const voyageRecords = [
{ shipId: 1, shipName: "POSSM", distance: 1000, fuelUse: 200 },
{ shipId: 2, shipName: "폴라리스", distance: 1500, fuelUse: 280 },
{ shipId: 1, shipName: "POSSM", distance: 800, fuelUse: 160 },
{ shipId: 3, shipName: "시도상선", distance: 2000, fuelUse: 400 },
];
console.log(analyzeShipFuelUsage(voyageRecords));
{
"ships": [
{
"shipId": 2,
"shipName": "폴라리스",
"distance": 1500,
"fuelUse": 280,
"efficiency": "5.36"
},
{
"shipId": 1,
"shipName": "POSSM",
"distance": 1800,
"fuelUse": 360,
"efficiency": "5.00"
},
{
"shipId": 3,
"shipName": "시도상선",
"distance": 2000,
"fuelUse": 400,
"efficiency": "5.00"
}
],
"totalFuelUsed": 1040
}
정리 ( 앞으로 공부 할 내용)
1. 고차 함수 (map(), forEach(), reduce(), sort() 등)의 동작 방식
2. 객체와 배열의 차이 및 변환 방법 (Object.values(), 배열 메서드 사용 등)
3. 함수 호출과 매개변수의 역할
5. 배열과 객체에서의 인덱스 및 키를 사용하는 방식
'🎒내가방 > 📒JavaScript' 카테고리의 다른 글
[모던 자바스크립트] this 키워드 (0) | 2024.10.22 |
---|---|
[모던 자바스크립트] 배열 고차 함수 (sort, forEach, map, filter) (0) | 2024.10.21 |
[자바스크립트] 상품을 필터링하기 (0) | 2023.07.01 |
[자바스크립트] 상품 목록 가져오기 (0) | 2023.07.01 |
[자바스크립트] 회원가입 할 때 패스워드 체크 기능 구현하기 (0) | 2023.06.29 |