본문 바로가기
JavaScript

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

by teamnova 2022. 7. 21.

안녕하세요. 오늘은 자바스크립트의 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>