• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

Kombinationen aus mehreren Arrays erstellen

F.Z

New member
hi,

ich habe die folgende object structur:

{
"Color": {name: "Color", values: ["red", "blue", "green"],
"Size": {name: "Size", values: ["S", "M", "L"],
....
}

was ich daraus jetzt bauen muss, is folgendes:

Color red, Size S,
Color red, Size M,
Color red, Size L,
Color blue, Size S,
Color blue, Size M,
....

wie krieg ich das hin? ich hab absolute keine Ahnung... Danke schon mal


greetings
 
Du musst über den Key Color iterieren, das ist die äußere Schleife. Und die innere ist über den Key Size, damit pro äußerem Element alle inneren ausgeführt werden.
 
Ich würde ja sagen, dass .forEach einfacher ist, da es so ziemlich das Gleiche macht und man kein Framework dafür braucht...
 
Vermutlich Geschmackssache. Ich empfinde ja vor allem JQuery als ein sehr einfaches Framework und möchte gar nicht mehr ohne Javascript schreiben. Man muss natürlich abwägen, ob sich ein Framework lohnt. Für jede Kleinigkeit macht es bestimmt keinen Sinn, aber spätestens bei einer größeren Webseite bzw. Webanwendung ist es sehr sehr praktisch.
 
Ich hab' ja auch nicht gesagt, dass man kein Framework verwenden soll. Aber wenn ich aber die Wahl habe zwischen einer nativen Funktion und einer aus dem Framework, die beide das Gleiche machen, würde ich mich immer für die native entscheiden - schon alleine, weil sie schneller ist.
Auch ist die Parameterwahl für den Callback bei jQuery mehr als ungünstig. Zusätzlich ist die native Schreibweise (meiner Meinung nach) verständlicher und kürzer:
Code:
var a = ["hallo", "das", "ist", "ein", "Test"];
a.forEach(function(el){
	alert(el);
});

// vs.

$.each(a, function(i, el){
	alert(el);
});
 
Hab' gerade gesehen, dass die API von jQuery nicht konsistent ist: jQuery.map() | jQuery API Documentation hat im Callback zuerst das Element und dann den Index. Ich werde immer mehr ihn meiner Entscheidung, jQuery nicht zu verwenden/mögen, bestärkt.

Für F.Z (die/der sich leider gar nicht mehr gemeldet hat) noch der Ansatz mit reduce (map funktioniert nicht so wirklich gut):
Code:
var data = {
	Color: {name: "Color", values: ["red", "blue", "green"]},
	Size: {name: "Size", values: ["S", "M", "L"]}
};

var text = data.Color.values.reduce(
	function(text, color){
		data.Size.values.reduce(
			function(text, size){
				text.push("Color " + color + ", Size " + size);
				return text;
			},
			text
		);
		return text;
	},
	[]
);

alert(text.join("\n"));
 
... dass die API von jQuery nicht konsistent ist: jQuery.map() | jQuery API Documentation hat im Callback zuerst das Element und dann den Index.
Hmm, das sind für mich Kleinigkeiten, die man durch Lesen der Doku beseitigen kann. Das ist für mich kein Grund JQuery nicht zu mögen...

Naja, ist ja auch egal. Jeder hat seine Vorlieben und Abneigungen.
 
Bitte zurück zu meinem Thema...

es ist so, dass dort beliebig viele Kombinationen / Arrays enthalten sein können. kann also keine festen Schleifen machen.
 
Die müssen nicht fest sein. Kannst auch über die Keys iterieren. Wieviel Erfahrung hast du generell in der Programmierung mal abgesehen von der JS Syntax?
 
arbeite seit paar Jahren in dem Beruf. aber hier hab ich leider gar kein Plan aktuell... evtl steh ich auch nur aufm Schlauch. helft mir doch bitte ^^
über die keys iterieren... und dann?
 
Aber wenn du schon länger programmierst musst du doch einen Plan haben, wie du über dein Object iterierst. Was ist denn der dritte, vierte, fünfte Key? Du kennst die Struktur doch besser als wir. Und die Syntax mit und ohne jQuery hast du oben schon gezeigt bekommen. Wo genau hakt es denn im Moment?
 
noch der Ansatz mit reduce (map funktioniert nicht so wirklich gut)
na das ist aber von hinten durch die brust ins auge.
selbst wenn man reduce als reduzierung auf ein array benutzt, ist das innere ein typisches map. du nutzt dein inneres reduce eigentlich als forEach.
also entweder so
Code:
var text = data.Color.values.reduce(function(arr, color)
{
  return arr.concat(data.Size.values.map(function(size)
  {
    return "Color " + color + ", Size " + size;
  }));
}, []);
oder so
Code:
text = [];
data.Color.values.forEach(function(color)
{
  var maped = data.Size.values.map(function(size)
  {
    return "Color " + color + ", Size " + size;
  });
  text = text.concat(maped);
});
 
Naja - so abwegig ist das nicht. Ich spare mir damit das .concat...

@F.Z: über Object.keys() bekommst du alle Schlüssel eines Objektes als Array. Darüber kannst du dann iterieren und schrittweise dein kartesisches Produkt aufbauen:
Code:
var data = {
	Color: {name: "Color", values: ["red", "blue", "green"]},
	Size: {name: "Size", values: ["S", "M", "L"]}
};

var text = Object.keys(data).reduce(
	function(textIn, key){
		var textOut = [];
		textIn.forEach(function(text){
			data[key].values.forEach(function(value){
				textOut.push(text + data[key].name + " " + value + ", ");
			});
		});
		return textOut;
	},
	[""]
).map(function(line){
	return line.substring(0, line.length - 2);
});

alert(text.join("\n"));
 
Naja - so abwegig ist das nicht.
nein, mich stört eher der name. sinn ist ja lesbareren code zu bekommen. und da finde ich reduce nicht gerade sinnvoll gewählt. besser finde ich da accumulate in c++ oder um bei js zu bleiben inject in underscore oder lodash, selbst foldl in ramda ist besser, wobei es schade ist, dass der alias auf inject dort nicht von haus aus enthalten ist.
ich bin eigentlich nur wegen dem 2. reduce darauf eingegangen, welches du nur als forEach nutzt
Code:
var text = data.Color.values.reduce(function(text, color)
{
  data.Size.values.forEach(function(size)
  {
    text.push("Color " + color + ", Size " + size);
  });
  return text;
}, []);
 
Ich finde reduce jetzt nicht so schlecht gewählt. Ist aber auch nicht so leicht, da ein prägnantes Wort dafür zu finden, denn unter inject würde ich mir auf den ersten Blick sowas wie ein .splice(i, 0, ...) vorstellen und eine Faltung ist, im mathematischen Sinn, auch eigentlich was anderes.

Mehr stören mich bei den ganzen Funktionen die bezeichnungen mit "left" und "right". In meinem Kopf hat ein Array einen Anfang und ein Ende und kein Links und Rechts - es gibt ja auch Leute, die von rechts nach links schreiben. So fände in .reduceReverse() oder .reduceBackwards() besser.

Aber ein Alias einzubauen ist ja nicht wirklich viel Arbeit/Aufwand.

Das Beispiel war extra ohne .forEach gebaut, um reduce zu zeigen. In Produktivcode würde ich das wahrscheinlich auch mit .forEach machen.
 
Zurück
Oben