JavaScript의 다차원 연관 배열


84

다음 쿼리 결과가 있습니다. (key1 및 key2는 임의의 텍스트 일 ​​수 있음)

id   key1     key2     value

1    fred     apple    2
2    mary     orange   10
3    fred     banana   7
4    fred     orange   4
5    sarah    melon    5
...

다음과 같이 모든 레코드를 반복 하는 그리드 (아마도 배열)에 데이터를 저장하고 싶습니다.

         apple    orange   banana  melon
fred        2        4         7     -
mary        -        10        -     -
sarah       -        -         -     5

PHP에서는 연관 배열을 사용하면 정말 쉽습니다.

$result['fred']['apple'] = 2;

그러나 이와 같은 JavaScript 연관 배열에서는 작동하지 않습니다. 수많은 자습서를 읽은 후 얻을 수있는 것은 다음과 같습니다.

arr=[];
arr[1]['apple'] = 2;

하지만 arr['fred']['apple'] = 2;작동하지 않습니다. 객체 배열을 시도했지만 객체 속성은 자유 텍스트가 될 수 없습니다. 튜토리얼을 더 많이 읽을수록 더 혼란스러워졌습니다 ...

어떤 아이디어라도 환영합니다 :)


회신 해 주셔서 감사합니다.하지만 쿼리 결과를 반복하고 있으며 한 번에 하나씩 값을 설정하고 싶습니다. 예제 행 (Matt 예제 형식) var grid = {};grid['aa']['bb'] = 1;은 "Uncaught TypeError : Cannot set property 'bb'of undefined"를 반환합니다. 내가 틀렸을 수도 있지만 대부분의 예제에서 초기화시 데이터를 알아야합니다.
Omiod

방금 그게 var grid = {}; grid['aa'] = {}; grid['aa']['bb'] = 1;효과가 있다는 것을 알았습니다 . 더 복잡한 테스트는 실패하지만 올바른 경로에있는 것 같습니다
Omiod

2
내 대답에서 언급했듯이 먼저 하위 개체를 초기화해야합니다. var grid = {}; grd [ 'aa'] = {}; 그런 다음 grid [ 'aa'] [ 'bb'] = 1을 수행 할 수 있습니다. 하위 개체가 이미 초기화되었는지 확인하는 여러 가지 방법이 있으므로 (내 답변에서 언급했듯이) 기존 항목을 덮어 쓰지 않습니다. 목적.
Matt

추가 코드로 내 대답을 업데이트했습니다. 당신이 당신의 데이터를 받고있어, 그러나 희망 옳은 방향으로 당신을 가리 킵니다 어떻게하지 않도록 얼마나 깊은 당신의 객체, 또는
매트

답변:


152

연관 배열과 동일한 방식으로 '읽는'일반 JavaScript 객체를 사용하십시오. 먼저 초기화하는 것을 기억해야합니다.

var obj = {};

obj['fred'] = {};
if('fred' in obj ){ } // can check for the presence of 'fred'
if(obj.fred) { } // also checks for presence of 'fred'
if(obj['fred']) { } // also checks for presence of 'fred'

// The following statements would all work
obj['fred']['apples'] = 1;
obj.fred.apples = 1;
obj['fred'].apples = 1;

// or build or initialize the structure outright
var obj = { fred: { apples: 1, oranges: 2 }, alice: { lemons: 1 } };

값을 살펴보면 다음과 같은 것이있을 수 있습니다.

var people = ['fred', 'alice'];
var fruit = ['apples', 'lemons'];

var grid = {};
for(var i = 0; i < people.length; i++){
    var name = people[i];
    if(name in grid == false){
        grid[name] = {}; // must initialize the sub-object, otherwise will get 'undefined' errors
    }

    for(var j = 0; j < fruit.length; j++){
        var fruitName = fruit[j];
        grid[name][fruitName] = 0;
    }
}

프로덕션 코드 (Chrome 확장)에서 예제를 사용하도록 관리했으며 제대로 작동합니다. 감사. 마지막으로 JS에서 객체를 처리하는 방법을 얻었습니다!
Omiod

3
이 답변을 충분히 찬성 할 수 없습니다! 내 개체가 계속해서 undefined를 반환하게 만든 부분은 하위 개체를 초기화하지 않았기 때문입니다. 그러니 꼭 이렇게하세요! 예 : grid[name] = {};
Jason Pudzianowski

1
@Matt 한 세트의 [] 만 사용하여 obj.fred.apples를 얻는 방법이 있습니까? 나는 그렇지 않다고 가정하고있다. obj["fred.apples"]
theB3RV

예를 들어 여러분의 코드 [javasript] var people = [ 'fred', 'alice']와 같이 배열의 수를 모른다면 어떻게 될까요? var fruit = [ '사과', '레몬']; var color = [ 'red', 'blue'] var
.....-

숫자 인덱스로 obj (fred)의 첫 번째 항목에 액세스 할 수 있습니까? 결과는 apples : 1, oranges : 2 인 obj [0]과 같습니다. 마지막 항목에 액세스 할 수 있습니까 (alice이고 결과는 레몬 : 1)?`
Timo

26

배열 일 필요 가없는 경우 "다차원"JS 객체를 만들 수 있습니다.

<script type="text/javascript">
var myObj = { 
    fred: { apples: 2, oranges: 4, bananas: 7, melons: 0 }, 
    mary: { apples: 0, oranges: 10, bananas: 0, melons: 0 }, 
    sarah: { apples: 0, oranges: 0, bananas: 0, melons: 5 } 
}

document.write( myObject[ 'fred' ][ 'apples' ] );
</script>

JSON은 실제로 JavaScript 객체의 '문자열'형식입니다. 당신이 가지고있는 것은 JSON이 아니라 단지 JavaScript 객체입니다.
Matt

고마워, 맷. 게시물을 업데이트했습니다.
charliegriefer 2010

1
@charliegriefer, document.write 줄은 "document.write (myObj ......"가 아니어야합니다.)
john

13

Javascript는 유연합니다.

var arr = {
  "fred": {"apple": 2, "orange": 4},
  "mary": {}
  //etc, etc
};

alert(arr.fred.orange);
alert(arr["fred"]["orange"]);
for (key in arr.fred)
    alert(key + ": " + arr.fred[key]);

8
변수 이름 'arr'은 실제로 배열이 아니라 객체이기 때문에 잘못된 이름이라고 말할 수 있습니다.
Matt

나는 게으른 개이므로 솔루션을 사용할 수 없습니다. 내가 열망했다면 하위 배열 예제로 내 길을 찾을 것입니다.) 어쨌든, 노력해 주셔서 감사합니다.
Timo

9

모든 요소를 ​​좋은 방식으로 가져와야했기 때문에 "2 차원 연관 배열 / 객체 이동"이라는 주제를 접했습니다. 이름에 관계없이 기능이 중요하기 때문입니다.

var imgs_pl = { 
    'offer':        { 'img': 'wer-handwritter_03.png', 'left': 1, 'top': 2 },
    'portfolio':    { 'img': 'wer-handwritter_10.png', 'left': 1, 'top': 2 },
    'special':      { 'img': 'wer-handwritter_15.png', 'left': 1, 'top': 2 }
};
for (key in imgs_pl) { 
    console.log(key);
    for (subkey in imgs_pl[key]) { 
        console.log(imgs_pl[key][subkey]);
    }
}

일반적으로 루프가가는 길이 기 때문에 대답을 받아 들여야합니다.
Timo

5

일부 애플리케이션의 경우 자바 스크립트에서 다차원 연관 배열에 대한 훨씬 더 간단한 접근 방식이있는 것으로 보입니다.

  1. 모든 배열의 내부 표현이 실제로 객체의 객체라는 점을 감안할 때, 숫자 인덱스 요소의 액세스 시간은 실제로 연관 (텍스트) 인덱스 요소의 액세스 시간과 동일하다는 것이 표시되었습니다.

  2. 첫 번째 수준의 연관 인덱스 요소에 대한 액세스 시간은 실제 요소 수가 증가해도 증가하지 않습니다.

이를 감안할 때, 다차원 요소의 동등성을 생성하기 위해 연결된 문자열 접근 방식을 사용하는 것이 실제로 더 나은 경우가 많이있을 수 있습니다. 예를 들면 :

store['fruit']['apples']['granny']['price] = 10
store['cereal']['natural']['oats']['quack'] = 20

로 이동:

store['fruit.apples.granny.price'] = 10
store['cereal.natural.oats.quack'] = 20

장점은 다음과 같습니다.

  • 하위 오브젝트를 초기화하거나 오브젝트를 최적으로 결합하는 방법을 알아낼 필요가 없습니다.
  • 단일 레벨 액세스 시간. 개체 내의 개체는 액세스 시간의 N 배 필요
  • Object.keys ()를 사용하여 모든 차원 정보를 추출 할 수 있습니다.
  • regex.test (string) 함수와 키에 array.map 함수를 사용하여 원하는 것을 정확하게 가져올 수 있습니다.
  • 차원에 계층이 없습니다.
  • "점"은 임의적입니다. 밑줄을 사용하면 실제로 정규식이 더 쉬워집니다.
  • JSON을이 형식 안팎으로 "평탄화"하기위한 많은 스크립트가 있습니다.
  • 키리스트에서 다른 모든 멋진 배열 처리 기능을 사용할 수 있습니다.

3

속성 이름이 정수인 경우 연관 배열의 속성 배열 값을 가져옵니다.

속성 이름이 정수인 연관 배열로 시작 :

var categories = [
    {"1":"Category 1"},
    {"2":"Category 2"},
    {"3":"Category 3"},
    {"4":"Category 4"}
];

항목을 어레이로 푸시합니다.

categories.push({"2300": "Category 2300"});
categories.push({"2301": "Category 2301"});

배열을 반복하고 속성 값으로 작업을 수행합니다.

for (var i = 0; i < categories.length; i++) {
    for (var categoryid in categories[i]) {
        var category = categories[i][categoryid];
        // log progress to the console
        console.log(categoryid + " : " + category);
        //  ... do something
    }
}

콘솔 출력은 다음과 같습니다.

1 : Category 1
2 : Category 2
3 : Category 3
4 : Category 4
2300 : Category 2300
2301 : Category 2301

보시다시피 연관 배열 제한을 피하고 속성 이름을 정수로 지정할 수 있습니다.

참고 : 내 예제의 연관 배열은 Dictionary [] 객체를 직렬화 한 경우 사용할 수있는 json입니다.


3

배열을 사용하지 말고 객체를 사용하십시오.

var foo = new Object();

2
new Object()Object.prototype에 이상한 점이 붙을 수 있으므로를 사용하지 마십시오 . 객체 리터럴 사용 :var foo = {};
Michael Paulukonis 2010

1
@Michael 나는 {}가 new Object (); []은 new Array ()의 약자입니다.
Matt

1
내 Chrome JS 콘솔에서이 두 constrcut은 프로토 타입을 포함하여 동일하게 보입니다. Object.prototype.foo = function () {}을 추가해도 둘 다 나타납니다.
Matt

1
@Matt 나는 내가 new Array()피해야 할 것과 섞어서 틀렸다고 생각 합니다. 으.
Michael Paulukonis 2010

1
@Michael 왜 new Array ()를 피해야합니까?
Matt

2

반드시 객체를 사용할 필요는 없으며 일반적인 다차원 배열로 할 수 있습니다.

이것은 Objects가없는 내 솔루션입니다 .

// Javascript
const matrix = [];

matrix.key1 = [
  'value1',
  'value2',
];

matrix.key2 = [
  'value3',
];

PHP에서는 다음과 같습니다.

// PHP
$matrix = [
    "key1" => [
        'value1',
        'value2',
    ],
    "key2" => [
        'value3',
    ]
];

1
나중에 어떻게 반복합니까 (각각 사용)?
Sagive SEO

0

<script language="javascript">

// Set values to variable
var sectionName = "TestSection";
var fileMap = "fileMapData";
var fileId = "foobar";
var fileValue= "foobar.png";
var fileId2 = "barfoo";
var fileValue2= "barfoo.jpg";

// Create top-level image object
var images = {};

// Create second-level object in images object with
// the name of sectionName value
images[sectionName] = {};

// Create a third level object
var fileMapObj = {};

// Add the third level object to the second level object
images[sectionName][fileMap] = fileMapObj;

// Add forth level associate array key and value data
images[sectionName][fileMap][fileId] = fileValue;
images[sectionName][fileMap][fileId2] = fileValue2;


// All variables
alert ("Example 1 Value: " + images[sectionName][fileMap][fileId]);

// All keys with dots
alert ("Example 2 Value: " + images.TestSection.fileMapData.foobar);

// Mixed with a different final key
alert ("Example 3 Value: " + images[sectionName]['fileMapData'][fileId2]);

// Mixed brackets and dots...
alert ("Example 4 Value: " + images[sectionName]['fileMapData'].barfoo);

// This will FAIL! variable names must be in brackets!
alert ("Example 5 Value: " + images[sectionName]['fileMapData'].fileId2);
// Produces: "Example 5 Value: undefined".

// This will NOT work either. Values must be quoted in brackets.
alert ("Example 6 Value: " + images[sectionName][fileMapData].barfoo);
// Throws and exception and stops execution with error: fileMapData is not defined

// We never get here because of the uncaught exception above...
alert ("The End!");
</script>


0
    var myObj = [];
    myObj['Base'] = [];
    myObj['Base']['Base.panel.panel_base'] = {ContextParent:'',ClassParent:'',NameParent:'',Context:'Base',Class:'panel',Name:'panel_base',Visible:'',ValueIst:'',ValueSoll:'',
                                              Align:'',  AlignFrom:'',AlignTo:'',Content:'',onClick:'',Style:'',content_ger_sie:'',content_ger_du:'',content_eng:'' };
    myObj['Base']['Base.panel.panel_top']  = {ContextParent:'',ClassParent:'',NameParent:'',Context:'Base',Class:'panel',Name:'panel_base',Visible:'',ValueIst:'',ValueSoll:'',
                                              Align:'',AlignFrom:'',AlignTo:'',Content:'',onClick:'',Style:'',content_ger_sie:'',content_ger_du:'',content_eng:'' };

    myObj['SC1'] = [];
    myObj['SC1']['Base.panel.panel_base'] = {ContextParent:'',ClassParent:'',NameParent:'',Context:'Base',Class:'panel',Name:'panel_base',Visible:'',ValueIst:'',ValueSoll:'',
                                              Align:'',  AlignFrom:'',AlignTo:'',Content:'',onClick:'',Style:'',content_ger_sie:'',content_ger_du:'',content_eng:'' };
    myObj['SC1']['Base.panel.panel_top']  = {ContextParent:'',ClassParent:'',NameParent:'',Context:'Base',Class:'panel',Name:'panel_base',Visible:'',ValueIst:'',ValueSoll:'',
                                              Align:'',AlignFrom:'',AlignTo:'',Content:'',onClick:'',Style:'',content_ger_sie:'',content_ger_du:'',content_eng:'' };


    console.log(myObj);

    if ('Base' in myObj) {
      console.log('Base found');

      if ('Base.panel.panel_base' in myObj['Base'])  {
        console.log('Base.panel.panel_base found'); 


      console.log('old value: ' + myObj['Base']['Base.panel.panel_base'].Context);  
      myObj['Base']['Base.panel.panel_base'] = 'new Value';
      console.log('new value: ' + myObj['Base']['Base.panel.panel_base']);
      }
    }

산출:

  • 자료 발견
  • Base.panel.panel_base를 찾았습니다.
  • 이전 값 : 기본
  • 새로운 가치 : 새로운 가치

어레이 작업이 작동합니다. 문제 없습니다.

되풀이:

     Object.keys(myObj['Base']).forEach(function(key, index) {            
        var value = objcons['Base'][key];                   
      }, myObj);

2
stackoverflow에 오신 것을 환영합니다. 답변을 수정하고 코드 조각이 문제를 해결하는 이유를 설명하십시오. 여기에 더 많은 정보를 원하시면 : 답변 방법
Djensen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.