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

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

Ответ 1

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

Ответ 2

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

Ответ 3

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

Ответ 4

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

Ответ 5

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

var foo = new Object();

Ответ 6

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

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

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

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

ПРИМЕЧАНИЕ. Ассоциативный массив в моем примере - это json, который вы имели бы, если бы вы сериализовали объект Dictionary [].

Ответ 7

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

Ответ 8

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

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

// Javascript
const matrix = [];

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

matrix.key2 = [
  'value3',
];

который в PHP эквивалентен:

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

Ответ 9

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