Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Многомерный ассоциативный массив (https://javascript.ru/forum/misc/23411-mnogomernyjj-associativnyjj-massiv.html)

cbone 22.11.2011 18:35

Как рекурсивно пройтись по ассоциативному многомерному массиву?
 
Всем привет.
Имеется многомерный ассоциативный массив:
var Config = {
		"БПИ": {
			"30": {
				"12": [ "2,5" ],
				"24": [ "1,25" ],
				"48": [ "0,65" ]
			},
			"60": {
				"12": [ "5,0" ],
				"24": [ "2,5" ],
				"36": [ "1,5" ],
				"48": [ "1,25" ]
			},
			"125": {
				"12": [ "10" ],
				"24": [ "5" ],
				"48": [ "2,5" ]
			},
			"250": {
				"12": [ "20,0" ],
				"24": [ "10,0" ],
				"48": [ "5,0" ]
			}
		}
	};

Как можно разбить данный массив на несколько индексных массивов, в которых будут содержаться элементы каждого подуровня. То есть для нашего примера будут массивы со следующими элементами:
arr[0] = ["БПИ"];
arr[1] = ["30","60","125","250"];
arr[2] = ["12","24","48","12","24","36","48","12","24","48"];

arr[3] по аналогии. Вложенность может быть ещё больше(то есть появятся arr[4], arr[5] и т.д. вплоть до arr[10].

ksa 23.11.2011 11:05

Цитата:

Сообщение от cbone
Вложенность может быть ещё больше(то есть появятся arr[4], arr[5] и т.д. вплоть до arr[10].

Это не "вложеность"... Это просто "следующие элементы". ;)

Gvozd 23.11.2011 11:20

Цитата:

Сообщение от ksa
Это не "вложеность"... Это просто "следующие элементы".

Месье, вы буквоед.
Внимательно перечитайте первый пост, и уловите мысль, которую пытался донести до нас автор, а не бросайтесь автоматическими фразами как собака павлова
cbone,
Пишите.
for( in ) для перебора
и перебираем рекурсивно.
там не две строчки кода, поэтому мне лениво писать за вас.

Aetae 23.11.2011 11:28

Чем дальше тем хуже.=\
Единственно правльный и логичный вариант в вашем случае уже был приведён в предыдущей теме, простые массивы, где заглавием является нулевой элемент.

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

ksa 23.11.2011 11:32

Цитата:

Сообщение от cbone
arr[0] = ["БПИ"]; 
arr[1] = ["30","60","125","250"]; 
arr[2] = ["12","24","48","12","24","36","48","12","24","48"];

Не совсем понятен алгоритм формирования того массива... Т.е. смущает элемент arr[2].
Ты записал туда все ключи "третьего уровня"...

Покажи как будет выглядеть твой массив на таком примере

var config = {
	"БПИ": {
		"30": {
			"12": [ "2,5" ],
			"24": [ "1,25" ],
			"48": [ "0,65" ]
		},
		"60": {
			"12": [ "5,0" ],
			"24": [ "2,5" ],
			"36": [ "1,5" ],
			"48": [ "1,25" ]
		},
		"125": {
			"12": [ "10" ],
			"24": [ "5" ],
			"48": [ "2,5" ]
		},
		"250": {
			"12": [ "20,0" ],
			"24": [ "10,0" ],
			"48": [ "5,0" ]
		}
	},
	"ВГИ": {
		"10": {
			"1": [ "2,5" ],
			"2": [ "1,25" ],
			"3": [ "0,65" ]
		},
		"20": {
			"1": [ "5,0" ],
			"2": [ "2,5" ],
			"3": [ "1,5" ],
			"4": [ "1,25" ]
		},
		"30": {
			"1": [ "10" ],
			"2": [ "5" ],
			"3": [ "2,5" ]
		},
		"40": {
			"1": [ "20,0" ],
			"2": [ "10,0" ],
			"3": [ "5,0" ]
		}
	}
};

ksa 23.11.2011 11:33

Цитата:

Сообщение от Gvozd
Месье, вы буквоед.

Термины - есть термины. Они означают то, что они означают... :nono:

Gvozd 23.11.2011 12:04

Цитата:

Сообщение от ksa
Термины - есть термины. Они означают то, что они означают...

поиграем в вашу игру.
Цитата:

Сообщение от cbone
Вложенность может быть ещё больше(то есть появятся arr[4], arr[5] и т.д. вплоть до arr[10].

О чьей вложенности сейчас говорится?
По-моему из контекста вполне однозначно ясно, что подразумевается вложенность исходного многомерного массива, и что если его вложенность возрастет на уровень, два, или более, то появятся элементы arr[4], arr[5] и т.д. вплоть до arr[10].
Или для Вас этот контекст не столь очевиден?

ksa 23.11.2011 13:38

Цитата:

Сообщение от Gvozd
О чьей вложенности сейчас говорится?

Массива arr...

Цитата:

Сообщение от Gvozd
Или для Вас этот контекст не столь очевиден?

Получается что так. :yes:

ksa 23.11.2011 13:59

Цитата:

Сообщение от cbone
Как можно разбить данный массив на несколько индексных массивов

Если я таки правильно понял проблемку - такой вот вариант например...

var config = {
	"БПИ": {
		"30": {
			"12": [ "2,5" ],
			"24": [ "1,25" ],
			"48": [ "0,65" ]
		},
		"60": {
			"12": [ "5,0" ],
			"24": [ "2,5" ],
			"36": [ "1,5" ],
			"48": [ "1,25" ]
		},
		"125": {
			"12": [ "10" ],
			"24": [ "5" ],
			"48": [ "2,5" ]
		},
		"250": {
			"12": [ "20,0" ],
			"24": [ "10,0" ],
			"48": [ "5,0" ]
		}
	}
};
var a=[],b,c;
var i,j,k;
for(i in config) {
	a[a.length]=new Array(i);
	b=[];
	c=[];
	for( j in config[i]) {
		b[b.length]=j;
		for( k in config[i][j]) {
			c[c.length]=k;
		};
	};
	a[a.length]=b;
	a[a.length]=c;
};
for (var i=0; i<a.length; i++) {
	alert('a['+i+'] = '+a[i]);
}

рони 23.11.2011 22:10

Вариант ...
var O = {
	"БПИ": {
		"30": {
			"12": [ "2,5" ],
			"24": [ "1,25" ],
			"48": [ "0,65" ]
		},
		"60": {
			"12": [ "5,0" ],
			"24": [ "2,5" ],
			"36": [ "1,5" ],
			"48": [ "1,25" ]
		},
		"125": {
			"12": [ "10" ],
			"24": [ "5" ],
			"48": [ "2,5" ]
		},
		"250": {
			"12": [ "20,0" ],
			"24": [ "10,0" ],
			"48": [ "5,0" ]
		}
	}
};
function look(h) {
    var b = [];
    return function (f, a) {
        var c, a = a || 0, d;
        !b[a] && (b[a] = []);
        for (d in f) if (b[a].push(d) && (c = f[d])&& typeof c=='object') {
            var g = {}, e;
            for (e in c) g[e] = c[e];
            arguments.callee(g, a + 1)
        }
        return b
    }(h)
};
var s=look(O).join('\n');
alert(s);

trikadin 23.11.2011 22:13

рони, ваш "вариант" ушёл в бесконечный цикл и повесил ff. Проверять надо же...

рони 23.11.2011 22:25

trikadin,
Поверьте ещё раз ... если интересно )))

trikadin 23.11.2011 22:43

рони, нормально. Что-то поменяли?

ksa 23.11.2011 22:59

Цитата:

Сообщение от рони
Поверьте ещё раз ... если интересно

А я нажал в Опере и ничего не дождался... :(

P.S.
Правда и мой вариант так же не запустился... :( Хотя на работе все показывало нормально.

melky 23.11.2011 23:02

Цитата:

Сообщение от рони (Сообщение 138634)
return function (f, a) {
var c, a = a || 0, d;
!b[a] && (b[a] = []);
for (d in f) if (b[a].push(d) && (c = f[d])&& typeof c=='object') {
var g = {}, e;
for (e in c) g[e] = c[e];

:-E вы всегда с такими именами переменных (a,b,c,d,e,f..) и такой кашей пишете? (я о использовании && вместо if(){} и т.д.)

рони 23.11.2011 23:21

ksa,
В опере тоже всё должно работать ...
melky,
Я по разному пишу ... но чаще так )))

ksa 24.11.2011 09:18

Цитата:

Сообщение от рони
В опере тоже всё должно работать ...

На работе таки работает. :yes:
Вот только что за нули в самой последней строке? Автор такого вроде не заказывал... :D

cbone 24.11.2011 12:53

Цитата:

Сообщение от Aetae (Сообщение 138524)
Ив вообще, скжите для чего вы хотите это использовать и мы предложим вам подходящие варианты.

Использовать хочу в интернет магазине. Продукция сложная и имеет много модификаций.
Вот пример на сайте http://en-i.ru/product-catalog/energ...ies/Pulse_BPI/ (форму можно посмотреть нажав на кнопку "Подобрать Импульсные БПИ)"
Тут как раз описаны БПИ. Но некоторая продукция имеет более сложную конфигурацию и кол-во модификаций может достигать 2000 с лишним. Для этого я хочу избавиться от нынешней формы подбора продукции и сделать так, чтобы пользователь просто выбрал нужную ему конфигурацию и нажал кнопку "Купить". При этом, выбирая определённые характеристики товара должна проходить проверка остальных характеристик и некоторые из них должны становиться некликабельными (именно те которые несовместимы с уже выбранными).
Пример того, что я хочу получить можно посмотреть здесь: http://quto.ru/BMW/1series/E81_E82_E87_E88/hatchback3d/ Там при подборе комплектации автомобиля (например при выборе объема двигателя 3л.) затемняются лишние характеристики и дизельный двигатель уже нельзя выбрать. Что то вроде этого я и хочу сделать для своего сайта.

cbone 24.11.2011 13:04

Цитата:

Сообщение от ksa (Сообщение 138553)
Если я таки правильно понял проблемку - такой вот вариант например...

var config = {
	"БПИ": {
		"30": {
			"12": [ "2,5" ],
			"24": [ "1,25" ],
			"48": [ "0,65" ]
		},
		"60": {
			"12": [ "5,0" ],
			"24": [ "2,5" ],
			"36": [ "1,5" ],
			"48": [ "1,25" ]
		},
		"125": {
			"12": [ "10" ],
			"24": [ "5" ],
			"48": [ "2,5" ]
		},
		"250": {
			"12": [ "20,0" ],
			"24": [ "10,0" ],
			"48": [ "5,0" ]
		}
	}
};
var a=[],b,c;
var i,j,k;
for(i in config) {
	a[a.length]=new Array(i);
	b=[];
	c=[];
	for( j in config[i]) {
		b[b.length]=j;
		for( k in config[i][j]) {
			c[c.length]=k;
		};
	};
	a[a.length]=b;
	a[a.length]=c;
};
for (var i=0; i<a.length; i++) {
	alert('a['+i+'] = '+a[i]);
}

Да, тут близко к тому что я хотел, но у массива config вложенность может быть ещё больше, например вот такой:
var config = {
	"БПИ": {
		"30": {
			"12": {
				"2,5": { 
					"да": [ "1,2", "3" ], 
					"нет": [ "1" ] 
				}
				},
			"24": [ "1,25" ],
			"48": [ "0,65" ]
		},
		"60": {
			"12": [ "5,0" ],
			"24": [ "2,5" ],
			"36": [ "1,5" ],
			"48": [ "1,25" ]
		},
		"125": {
			"12": [ "10" ],
			"24": [ "5" ],
			"48": [ "2,5" ]
		},
		"250": {
			"12": [ "20,0" ],
			"24": [ "10,0" ],
			"48": [ "5,0" ]
		}
	}
};

ksa 24.11.2011 13:07

Цитата:

Сообщение от cbone
но у массива config вложенность может быть ещё больше,

Тогда есть два путя... :D
3. Добавлять циклов и временных массивов до нужного количества уровней...
2. Таки делать рекурсию.

cbone 24.11.2011 13:15

Цитата:

Сообщение от ksa (Сообщение 138712)
2. Таки делать рекурсию.

Этот путь мне кажется более универсальным и логичным.

ksa 24.11.2011 13:15

cbone, хозяин - барин... :)

cbone 08.12.2011 12:21

Реализовал я поставленную задачу. Также сделал подборщика. Может кому пригодится:
$(document).ready(function() {
	//Задали массивы
	var ConfigName = ["Наименование", "Мощность, Вт", "Напряжение, В", "Ток, А"]; //Массив для названия каждого уровня массива Config
	var Config = {
			"БПИ": {
				"30": {
					"12": [ "2.5" ],
					"24": [ "1.25" ],
					"48": [ "0.65" ]
				},
				"60": {
					"12": [ "5.0" ],
					"24": [ "2.5" ],
					"36": [ "1.5" ],
					"48": [ "1.25" ]
				},
				"125": {
					"12": [ "10.0" ],
					"24": [ "5.0" ],
					"48": [ "2.5" ]
				},
				"250": {
					"12": [ "20.0" ],
					"24": [ "10.0" ],
					"48": [ "5.0" ]
				}
			}
	};
	
	//##############################################################################
	
	// Рекурсивная функция для вывода конфигураций товара
	var ResultArray = [];
	var current_level = -1;
	
	function Recursion(Arr){
		current_level++;
		if(Arr instanceof Object){
			for ( var key in Arr) {
				if (Arr instanceof Array) {
					content = Arr[key];
				} else if (Arr instanceof Object) {
					content = key;
				}
				
				if(ResultArray[current_level] == null) {
					ResultArray[current_level] = content+";";
				} else {
					if(ResultArray[current_level].indexOf(content) == -1) {
						ResultArray[current_level] = ResultArray[current_level]+content+";";
					}
				}
								
				Recursion(Arr[key]);
			}
		}
		current_level--;
	}
	
	Recursion(Config); //Вызвали рекурсивную функцию 
	
	/* наводим порядок в массиве ResultArray[] и переносим данные в двумерный массив */
	var SplitArray = [];
	for ( var int = 0; int < ResultArray.length; int++) {
		ResultArray[int] = ResultArray[int].slice(0, -1);
		SplitArray[int] = ResultArray[int].split(";");
		
	}
	
	/* Вывод формы подбора в браузер */
	for ( var int = 0; int < ConfigName.length; int++) {
		if(int == 0) {
			$("#wrap").append("<dl></dl>");
		} else {
			$("#wrap").append("<dl class=\"dn\"></dl>");
		}
		$("#wrap dl:eq("+int+")").append("<dt>"+(int+1)+". "+ConfigName[int]+":</dt>");
		for ( var int2 = 0; int2 < SplitArray[int].length; int2++) {
			$("#wrap dl:eq("+int+")").append("<dd><span><a class=\"das\" href=#>"+SplitArray[int][int2]+"</a></span></dd>");
		}
	}
	
	/* Обработка событий */
	$("a.das").click(function(){
		var current_dl = $(this).parents("dl").index(); // Текущий <dl>
		var length_conf = $("dl").size(); // К-во <dl>
		
		
		/* Убрали лишние class="active" */
		for(var int=current_dl; int<length_conf; int++){
			$("dl:eq("+int+") span").removeClass("active");
		}
		
		/* Добавили нужному элементу class="active" и убрали всем лишним на текущем уровне */
		$(this).parents("dl").find("span").removeClass("active");
		$(this).parent("span").toggleClass("active");
		
		/* Формируем массив active_arr[] */
		var active_arr = []; // Массив для хранения <span class="ACTIVE">
		for ( var int = 0; int < current_dl; int++) {
			active_arr[int] = $("dl:eq("+int+") span.active a.das").text();
		}

		/* Формируем массив, содержащий конфигурацию для следующего подуровня */
		var ConfigTemp = Config;
		for ( var int=0; int<active_arr.length; int++) {
			ConfigTemp = ConfigTemp[active_arr[int]];
		}
		var correct_arr = [];
		for ( var key in ConfigTemp) {
			if (current_dl < (length_conf-1)) {
				correct_arr.push(key);
			} else {
				correct_arr.push(ConfigTemp[key]);
			}
			
		}
		
		/* Скрыли все <dd> следующего уровня */
		$("dl:eq("+(current_dl)+") dd").hide();
		
		/* Показали только подходящие */
		count_dd = $("dl:eq("+(current_dl)+") dd").length;
		
		for ( var int = 0; int < correct_arr.length; int++) {
			for(var int2=0; int2<count_dd; int2++) {
				if( $("dl:eq("+(current_dl)+") dd:eq("+int2+") span a").text() == correct_arr[int] ) {
					$("dl:eq("+(current_dl)+") dd:eq("+int2+")").show();
				}
			}
		}
		
		$(this).parents("dl").nextAll("dl").delay(200).hide(); //Скрыли
		$(this).parents("dl").next("dl").fadeIn(); //Показали
		
		if(count_dd == 0) {
			$("form").fadeIn();
		} else {
			$("form").hide();
		}
		
		return false;
	});
	
	$("form input[type=submit]").click(function(){
		//var query = 
		return false;
	});
});

Если кому интересно посмотреть рабочий пример, пишите в личку - дам ссылку.

Henocra 18.11.2014 15:17

помогите найти ошибку в коде
var mas = new Array();
mas[0] = new Array();
mas[0] = "aaa";
mas[1] = new Array();
mas[1] = "bbb";

рони 18.11.2014 15:29

Цитата:

Сообщение от Henocra
mas[0] = "aaa";

mas[0][0] = "aaa";
Цитата:

Сообщение от Henocra
mas[1] = "bbb";

mas[1][0] = "bbb";


Часовой пояс GMT +3, время: 09:22.