2014-11-30 3 views
0

부모 배열과 자식 배열을 만들고 나중에 각 부모 배열에 자식 배열을 설정하려고합니다. 여기 Javascript는 다른 배열 요소의 속성으로 배열을 배열합니다.

코드이다

var parent = []; 
var child = []; 

// Set kids 
for (a = 0; a <= 5; a++) { 
    child[a] = []; 
    child[a].name = "kid " + a; 
} 

// Set parents and their kids 
for (b = 0; b < 2; b++) { 
    parent[b] = []; 
    parent[b].name = "parent " + b; 
    parent[b].kids = child; 
} 

// One parent has kid name anna 
parent[0].kids[2].name = "anna"; 

// Output 
for (a = 0; a < 2; a++) { 
    console.log(""); 

    for (b = 0; b < 5; b++) { 
     console.log(b + " -> " + parent[a].name + " " + parent[a].kids[b].name); 
    } 
} 

먼저 상위

0 -> 부모 0 아이 0

1 -> 부모 0 아이 1

2 -> 부모 0 안나

3 -> 부모 0 아이 3

4 -> 부모 0 아이 4


번째 상위

0 -> 상위 1 아이 0

1 -> 상위 1 명 아이 1

2 -> 상위 1 안나

3 -> 상위 1 명 아이 3

4 -> 상위 1 아이


4 이유는 두 부모가 한 아이의 이름 애나을 가져야 만 먼저 같은 아이들이 어떻게, 그리고 더 중요한 것은 어떻게 제대로 작동하도록 만들 수 있습니까?

+0

. 모든 .kids 속성을 동일한'child' 배열로 설정했기 때문에. 객체와 배열은 JS가 아닌 참조에 의해 전달됩니다. 또한 parent {b] = []; 대신 새 parentent/child 즉'parent [b] = {};에 대한 배열이 아닌 객체를 만들고 싶을 것입니다. –

+0

'parent [b] .kids = child;'. 따라서 모든 '종류'는 '자식'객체와 동일한 객체 참조입니다. – dfsq

답변

1

새로 만든 개체에 배열에 대한 참조를 전달하기 때문에.

var a = [1,2,3,4]; 
var b = a; 
b[0] = 2; 
a[0] === 2; // true 

(복제 된) 새 어레이를 보내려는 경우. 당신은 할 수 있습니다 :

for (b = 0; b < 2; b++) { 
    parent[b] = []; 
    parent[b].name = "parent " + b; 
    parent[b].kids = child.slice(); // Slice creates a new array from the old 
} 

편집 @dfsq 원래 질문 제공된 코드에 진술했다 1

, 당신은 실제로 배열 객체를하지 사용하고 있습니다. 개체를 복제하는 가장 좋은 방법이 무엇인지에 대한 논의에 깊은 것없이,이 경우 안전하게 수행 할 수의 당신이 당신의 코드에서 jQuery를 사용한다고 가정하자 :

parent[b].kids = $.extend({}, child); 

더 객체 작업에 대한 당신이 읽을 수 있습니다 Mozilla Developer Network.

+0

OP는 객체로서 배열을 사용하기 때문에 ('.name' 속성 설정),이 경우에는'slice'가 도움이되지 않습니다. – dfsq

+0

@dfsq 수정하십시오. 내 대답이 업데이트됩니다. – drinchev

1

이미 언급했듯이 모든 부모에게 동일한 하위 배열을 할당하는 것이 문제입니다.

어레이 child에 프리미티브 값이 포함 된 경우 배열을 복사 한 다음 kids 속성을 설정하는 방법을 사용하면 얕은 복사본만으로 충분하므로 실제로 도움이됩니다. 그러나 요소는 프리미티브가 아니기 때문에 여기에 제시된 문제는 좀 더 복잡해 지므로 딥 복사 방법을 사용해야합니다.

즉, 전체 배열을 복사 할뿐만 아니라 모든 단일 항목의 복사본을 별도로 만들어야합니다.

부모에게 할당 할 때마다 자녀를 복사하는 것과 같은 방법을 사용할 수 있습니다. 이것은 가장 빠르지 만 가장 아름다운 방법은 아니지만 시작하기에 충분해야합니다.

function clone(obj) { 
    if(obj == null || typeof(obj) != 'object') 
     return obj; 

    var temp = obj.constructor(); // changed 

    for(var key in obj) { 
     if(obj.hasOwnProperty(key)) { 
      temp[key] = clone(obj[key]); 
     } 
    } 
    return temp; 
} 

function copy_kids(kids) { 
    var new_kids = []; 
    for (var kid_id = 0; kid_id < kids.length; ++kid_id) { 
     new_kids[kid_id] = clone(kids[kid_id]); 
    } 
    return new_kids; 
} 

older answer에서 개체를 복사하는 기능이 사용되었습니다.

는 다음을 변경, 코드를 작동하게하려면

// Older 
parent[b].kids = child; 

// Newer 
parent[b].kids = copy_kids(child); 

이 완전히 정확하려면이 정말 깊은 복사가 아니라 배열 자체를 복사하는 것보다 조금 더 깊이. 심도 대 얕은 복사에 대한 자세한 내용은 here을 참조하십시오.

관련 문제