JavaScript

[JavaScript] find 함수에 대해 알아보고 네이버지도 api 에서 사용해보기

teamnova 2022. 7. 21. 00:00
728x90

안녕하세요. 오늘은 자바스크립트의 find 함수에 대해 알아보고 네이버지도 api 에서 사용해보겠습니다.

 

find() 함수는 배열 내에서 조건을 만족하는 첫번째 요소의 값을 찾아서 반환하는 함수입니다. 조건을 만족하는 요소가 없다면 undefined 를 반환합니다. 

 

find 함수의 구문은 아래와 같습니다.

arr.find(callbackFunction(element, index, array), thisArg)

find 함수의 매개변수는 callbackFunction, 그리고 thisArg 입니다.

 

callbackFunction 에는 3개의 매개변수를 사용할 수 있습니다.

- element : 현재 요소 (필수)

- index : 요소의 인덱스 (선택)

- array : find 함수를 호출한 배열 (선택)

 

thisArg는 callbackFunction을 실행 할 때 this로 사용하는 값입니다. (선택)

 

간단한 예제로 find 함수의 사용법을 익혀보겠습니다. 

먼저 다음과 같이 학생들의 정보를 담은 students 라는 배열을 생성합니다.

var students = [
  { id: 1784, name: 'Andy Kim' },
  { id: 2816, name: 'Susan Park' },
  { id: 6077, name: 'Peter Ko' },
  { id: 4180, name: 'Jason Lee' }
];

 

해당 배열에 'id' 키의 값이 6077인 요소가 있는지 확인하고, 해당 조건('id' 키의 값이 6077)을 만족하는 요소를 발견하면 리턴시키는 코드는 다음과 같습니다.

var student1 = students.find(function (obj) {
    return obj.id === 6077;
});
console.log(student1); // {id: 6077, name: 'Peter Ko'}

 

ES6의 화살표 함수를 사용하면 좀더 간결하게 코드를 짤 수 있습니다. 이번에는 students 배열에서 'name' 키의 값이 'Jason Lee' 인 요소를 찾아서 반환하는 코드입니다.

var student2 = students.find(obj => obj.name === 'Jason Lee');
console.log(student2); // {id: 4180, name: 'Jason Lee'}

 

 

 

다음으로, find 함수를 네이버지도 api 에서 활용해보겠습니다. 

네이버지도 api 의 기본 사용법은 7월 6일자 포스팅([Javascript] 네이버 지도 api 를 사용해서 지도 표시 및 마커 찍기)을 참고해주세요.

 

 

먼저 <body> 태그 안에 지도가 표시될 DOM 요소와 장소 검색을 하기 위한 <input>, <button> 요소를 추가합니다.

<div style="display: flex;">
	<div id="map" style="width:100%; height:800px; margin-right: 10px;"></div>
	<div>
		<input type="text" placeholder="장소 이름을 입력하세요" id="placeInput" style="padding: 8px; font-size: 16px; margin-bottom: 10px;">
		<button type="button" onclick="checkPlace();" style="padding: 8px; font-size: 16px;">장소 찾기</button>
	</div>
</div>

 

지도를 생성하고, 마커를 생성하기 위한 장소 정보를 담는 배열을 생성합니다.

// 지도 생성
var map = new naver.maps.Map('map', {
    center: new naver.maps.LatLng(37.5112, 127.0981), // 잠실 롯데월드를 중심으로 하는 지도
    zoom: 14
});

// 지도에 마커를 표시할 장소들에 대한 정보를 담는 배열 (장소명, 위도, 경도)
const places = [
    {
        name: '롯데월드', // 장소명
        lat: 37.5112, // 위도
        lng: 127.0981 // 경도
    },
    {
        name: '올림픽공원',
        lat: 37.5212, 
        lng: 127.1215
    },
    {
        name: '가락시장',
        lat: 37.4935, 
        lng: 127.1098
    },
    {
        name: '잠실올림픽주경기장',
        lat: 37.5161, 
        lng: 127.0728
    },
    {
        name: '방이역',
        lat: 37.5087, 
        lng: 127.126
    },
    {
        name: '선릉역',
        lat: 37.5047, 
        lng: 127.0489
    },
];

 

마커들을 담을 배열도 생성합니다. 앞서 만든 places 라는 배열의 길이만큼 마커를 생성합니다. 이 때 마커를 식별하기 위해서 html 아이콘 방식으로 마커를 생성해보겠습니다. 

// 마커 정보를 담는 배열
const markers = new Array();

// places 배열의 길이만큼 마커를 생성하기
for (var i = 0; i < places.length; i++) {
    // 마커 생성
    var marker = new naver.maps.Marker({
        position: new naver.maps.LatLng(places[i].lat, places[i].lng),
        map: map,
        name: places[i].name,
        icon: { // html 아이콘
            content: '<div style="width: 100px; text-align: center; padding: 8px; background: white; border: solid 1px black;">' + places[i].name + '</div>',
            size: new naver.maps.Size(38, 58),
            anchor: new naver.maps.Point(19, 58),
        },
    });

    markers.push(marker); // 생성한 마커를 markers 배열에 담기
}

 

그리고 checkPlace() 라는 함수는 다음과 같습니다. 버튼을 누르면 <input> 요소에 입력한 값을 얻어서, 앞서 생성한 마커들 중에 입력값과 일치하는 'name' 키값을 가지는 마커가 있는지 find() 함수를 사용해서 검사합니다. 일치하는 마커가 있으면 그 마커에 애니메이션 효과를 부여하고, 일치하는 마커가 없다면 alert 메세지를 띄웁니다.

function checkPlace() {
    // <input> 요소를 선택하고 해당 요소의 값을 얻기
    var inputVal = document.getElementById("placeInput").value;

    // markers 배열 내에서 'name' 키의 값이 <input>에 입력한 값과 일치하는 마커가 있는지 찾기
    var selectedMarker = markers.find(obj => obj.name === inputVal);
    console.log(selectedMarker);

    if (selectedMarker != undefined) {
        // 일치하는 마커가 있으면 해당 마커에 애니메이션 효과 주기
        selectedMarker.setAnimation(naver.maps.Animation.BOUNCE);
    } else {
        // 일치하는 마커가 없으면 undefined가 반환됨
        alert('찾는 장소에 해당하는 마커가 없습니다.');
    }

    // <input> 요소의 값 초기화
    document.getElementById("placeInput").value = '';
}

 

다음은 시연 영상입니다.

 

다음은 전체 코드입니다.

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no">
    <title>네이버지도 스틱코드</title>
    <!-- 네이버지도 api -->
    <script type="text/javascript" src="https://openapi.map.naver.com/openapi/v3/maps.js?ncpClientId=YOUR_CLIENT_ID"></script>
</head>
<body>
    <div style="display: flex;">
        <div id="map" style="width:100%; height:800px; margin-right: 10px;"></div>
        <div>
            <input type="text" placeholder="장소 이름을 입력하세요" id="placeInput" style="padding: 8px; font-size: 16px; margin-bottom: 10px;">
            <button type="button" onclick="checkPlace();" style="padding: 8px; font-size: 16px;">장소 찾기</button>
        </div>
    </div>

    <script>

    // 지도 생성
    var map = new naver.maps.Map('map', {
        center: new naver.maps.LatLng(37.5112, 127.0981), // 잠실 롯데월드를 중심으로 하는 지도
        zoom: 14
    });

    // 지도에 마커를 표시할 장소들에 대한 정보를 담는 배열 (장소명, 위도, 경도)
    const places = [
        {
            name: '롯데월드', // 장소명
            lat: 37.5112, // 위도
            lng: 127.0981 // 경도
        },
        {
            name: '올림픽공원',
            lat: 37.5212, 
            lng: 127.1215
        },
        {
            name: '가락시장',
            lat: 37.4935, 
            lng: 127.1098
        },
        {
            name: '잠실올림픽주경기장',
            lat: 37.5161, 
            lng: 127.0728
        },
        {
            name: '방이역',
            lat: 37.5087, 
            lng: 127.126
        },
        {
            name: '선릉역',
            lat: 37.5047, 
            lng: 127.0489
        },
    ];

    // 마커 정보를 담는 배열
    const markers = new Array();

    // places 배열의 길이만큼 마커를 생성하기
    for (var i = 0; i < places.length; i++) {
        // 마커 생성
        var marker = new naver.maps.Marker({
            position: new naver.maps.LatLng(places[i].lat, places[i].lng),
            map: map,
            name: places[i].name,
            icon: { // html 아이콘
                content: '<div style="width: 100px; text-align: center; padding: 8px; background: white; border: solid 1px black;">' + places[i].name + '</div>',
                size: new naver.maps.Size(38, 58),
                anchor: new naver.maps.Point(19, 58),
            },
        });

        markers.push(marker); // 생성한 마커를 markers 배열에 담기
    }


    function checkPlace() {
        // <input> 요소를 선택하고 해당 요소의 값을 얻기
        var inputVal = document.getElementById("placeInput").value;
        
        // markers 배열 내에서 'name' 키의 값이 <input>에 입력한 값과 일치하는 마커가 있는지 찾기
        var selectedMarker = markers.find(obj => obj.name === inputVal);
        console.log(selectedMarker);

        if (selectedMarker != undefined) {
            // 일치하는 마커가 있으면 해당 마커에 애니메이션 효과 주기
            selectedMarker.setAnimation(naver.maps.Animation.BOUNCE);
        } else {
            // 일치하는 마커가 없으면 undefined가 반환됨
            alert('찾는 장소에 해당하는 마커가 없습니다.');
        }

        // <input> 요소의 값 초기화
        document.getElementById("placeInput").value = '';
    }

    </script>

</body>
</html>