Многомерные ассоциативные массивы в JavaScript

есть следующие результаты запроса: (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; не работает. Я пробовал массивы объектов, но свойства объектов не могут быть свободным текстом. Чем больше я читал учебники, тем больше запутывался...

любая идея приветствуется :)

9 ответов


просто используйте обычный объект 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;
    }
}

, если не есть чтобы быть массивом, вы можете создать "многомерный" объект 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>

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]);

поскольку мне нужно было получить все элементы хорошим способом, я столкнулся с этой темой. обход 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]);
        }//for

    }//for

Не используйте массив, используйте объект.

      var foo = new Object();

получить значение для массива ассоциативных массивов свойства, когда имя свойства является целым числом:

начиная с ассоциативного массива, где имена свойств являются целыми числами:

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

Push элементы в массив:

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

как вы можете видеть, вы можете обойти ограничение ассоциативного массива и имя свойства должно быть целым числом.

Примечание: ассоциативный массив в моем примере-это json, который вы имели бы, если бы сериализовали объект Dictionary [].


похоже, что для некоторых приложений существует гораздо более простой подход к многомерным ассоциативным массивам в javascript.

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 раз время доступа
  • можно использовать объект.ключи () для извлечения всей информации об измерении и..
  • можно использовать функцию regex.тест (строка) и массив.функция карты на клавишах, чтобы вытащить именно то, что вы хотите.
  • нет иерархии в измерениях.
  • "точка" произвольна-использование подчеркивания фактически упрощает регулярное выражение
  • есть много сценариев для "сплющивания" JSON в и из этого формата, а также
  • можно использовать все из других приятных функций обработки массива на keylist

вам не нужно обязательно использовать объекты, вы можете сделать это с нормальным многомерные массивы.

Это мое решение без объектов:

// Javascript
const matrix = [];

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

matrix.key2 = [
  'value3',
];

что в PHP эквивалентно:

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

<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>