Map 인스턴스 복제 / 복사


87

자바 스크립트에서 맵을 어떻게 복제 / 복사하나요?

어레이를 복제하는 방법을 알고 있지만 맵을 복제 / 복사하려면 어떻게합니까?

var myArray = new Array(1, 2, 3);
var copy    = myArray.slice();
// now I can change myArray[0] = 5; & it wont affect copy array

// Can I just do the same for map?
var myMap = new ?? // in javascript is it called a map?
var myMap = {"1": 1, "2", 2};
var copy  = myMap.slice(); 

2
ES6를 사용하면let copy = {...myMap};
Reactgular

답변:


17

단순 복사를 수행하는 간단한 방법은 소스 맵의 각 속성을 대상 맵에 복사하는 것입니다.

var newMap = {};
for (var i in myMap)
   newMap[i] = myMap[i];

참고 : newMap [i]는 myMap [i]와 동일한 객체에 대한 참조 일 수 있습니다.


6
이것은 얕은 사본 일뿐입니다 ... myMap [i]가지도 자체이면 어떻게됩니까?
Stefano

1
Stefano, 원한다면 그렇게 할 수 있습니다. 당신을 무한 루프에 빠뜨리는 조상 요소가 될 가능성. 정말 깊은 사본을 원하면 라이브러리를 살펴보고 싶을 수 있습니다.
rob

4
나도 알아,하지만 난 당신이 ;-) 처음에 답이 작성했습니다한다고 생각
스테파노

5
이것은지도가 아니라 개체입니다. 작고 미묘한 차이. cf. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
helt

1
그것은 당신이 단지 개체로 세터와 게터에 대한 접근이 실 거예요 각 속성을 복사하지 않습니다
Amante 닌자

328

자바 스크립트에지도가 도입됨에 따라 생성자가 이터 러블을 허용한다는 점을 고려하면 매우 간단합니다.

var newMap = new Map(existingMap)

문서 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map


4
위의 작은주의 사항 : 이와 같은 맵을 복제하면 Map.prototype.entriesMap.prototype.set. 그 말 : 당신이지도 확장하는 클래스 작성하는 경우 단순히 쓰기, 중 이러한 두 가지 방법의 덮어 쓰기를 new ExtendedMap( extendedMapObj )합니다 확장 방법은 슈퍼에 사용할 수없는 특성에 의존하는 경우없는 일.

딥 클론인가요 아니면 얕은 클론인가요? 하자 내가 값으로 중첩 된 객체가 있다고 가정
Madeo

하지만 딥 또는 얕은 복사를합니까 ??
Yonatan Nir

5
이것은 깊지 않은 얕은 복사를 할 것입니다 : jsfiddle.net/jormwe69
Jaap

1
@PeterCoester 캔은 우리의 점근 말할 var newMap = new Map(existingMap)이다가 O(n)어디 n맵의 키 / 값 쌍의 수? O(1)당신이 말했듯 Map.prototype.entries 이 내부적으로 호출 된다면 복제 작업은 일정하지 않은 것 같습니다 .
tonix

11

당신이 말하는 것은 단지 객체이기 때문에 맵을 복제하는 것은 매우 간단합니다. MapES6 에는 조회해야하는 항목이 있지만 객체를 복사하려면 다음을 사용하십시오.Object.assign()

let map = {"a": 1, "b": 2}
let copy = Object.assign({}, map);

cloneDeep()Lodash 에서도 사용할 수 있습니다.

let copy = cloneDeep(map);

6

JQuery에는 객체를 확장 (두 객체 병합)하는 방법이 있지만이 방법은 빈 객체를 제공하여 객체를 복제하는 데 사용할 수도 있습니다.

// Shallow copy
var newObject = jQuery.extend({}, oldObject);

// Deep copy
var newObject = jQuery.extend(true, {}, oldObject);

더 많은 정보는 jQuery 문서 에서 찾을 수 있습니다 .


3

내장 된 것이 없습니다.

잘 테스트 된 재귀 속성 복사기를 사용하거나 성능이 문제가되지 않는 경우 JSON으로 직렬화하고 새 개체로 다시 구문 분석합니다.


2

기본 제공 클론 / 복사본이 없습니다. 얕은 또는 전체 복사에 고유 한 메서드를 작성할 수 있습니다.

function shallowCopy(obj) {
    var result = {};
    for (var i in obj) {
        result[i] = obj[i];
    }
    return result;
}

function deepCopy(obj) {
    var result = {};
    for (var i in obj) {
        // recursion here, though you'll need some non-trivial logic
        // to avoid getting into an endless loop.
    }
    return result;
}

Javascript의 모든 개체는 동적이며 새 속성을 할당 할 수 있습니다. "지도"는 실제로는 빈 개체 일뿐입니다. 배열은 또한 다음과 같은 방법으로 목적, slice추천 및 특성 length.


작성한 두 함수의 차이점을 이해하지 못했습니다!
Hasan A Yousef

@HasanAYousef 차이점은 구현되지 않았습니다. 딥 카피에서는 재귀 (각 자식에 대해 deepCopy 호출)해야하지만 자식에 부모에 대한 참조 (예 : window.window2 = window)가 포함될 수 있으므로 무한 루프에 들어 가지 않고는 해당 참조를 딥 복사 할 수 없습니다.
니콜

2

지도의 전체 복사본을 만들어야하는 경우 다음을 사용할 수 있습니다.

new Map(JSON.parse(JSON.stringify(Array.from(source))));

source원래 Map 객체는 어디에 있습니까 ?

이는 Map 값이 직렬화되지 않는 모든 사용 사례에 적합하지 않을 수 있습니다. 자세한 내용은 https://stackoverflow.com/a/122704/10583071을 참조하십시오.


jsperf에서 테스트를 실행 한 결과 반복적 인 접근 방식이 10 배 더 빠르다는 것을 알았습니다
Zack Burt

2
@ZackBurt 슬프게도, 당신의 빠른 제안 된 대안은 정말 만들지 않습니다 deep copy대상의를 Map그냥입니다 shallow copy. 아마도 이것이 그렇게 빠른 이유일까요?
Alfonso M. García Astorga

@ AlfonsoM.GarcíaAstorga 명확하게 해주셔서 감사합니다. 딥 카피 가 아니라는 점에서 정확합니다 . 그러나 10kb 미만의 데이터로 더 빠른 사본입니다. 권장 보충 자료 : v8.dev/blog/cost-of-javascript-2019#json
Zack Burt

1

Map은 특별한 처리가 필요하므로이 스레드의 모든 제안을 통해 코드는 다음과 같습니다.

function deepClone( obj ) {
    if( !obj || true == obj ) //this also handles boolean as true and false
        return obj;
    var objType = typeof( obj );
    if( "number" == objType || "string" == objType ) // add your immutables here
        return obj;
    var result = Array.isArray( obj ) ? [] : !obj.constructor ? {} : new obj.constructor();
    if( obj instanceof Map )
        for( var key of obj.keys() )
            result.set( key, deepClone( obj.get( key ) ) );
    for( var key in obj )
        if( obj.hasOwnProperty( key ) )
            result[key] = deepClone( obj[ key ] );
    return result;
}

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.