JS: nur mehrfach vork. Elemente zählen

nietaL

NGBler
Registriert
8 Sep. 2013
Beiträge
231
Ort
Exilgullianer
Ich möchte, dass alle Elemente aus dem Beispiele mit einer 1 am Anfang gezählt werden, alle anderen nicht.
Beim Zählen sollen aber alle gezählt werden, die die erste drei Ziffen gleich haben.

Beispielergebnis in Bezug auf das Array numID (s.u.)
131xxxx 1x
111xxxx 3x
3318463 (bleibt ungezählt)

Die IDs sollen in einzelne Bilder umgewandelt werden.
Die IDs ohne vorangestellte 1 funktionieren bereits. Aber beim unteren Abschnitt meines Codes bricht alles zusammen.
Problem ist, dass er nicht die 111 dreimal durchzählt, weil es beim iterieren ja sonst 3x3=9 würden.


[src=javascript]

var numID = [1311673;1116253;1115264;1117243;3328463]

var numID = document.getElementById("truppe").value.split(";");
var bilder = "";


numID.forEach(add);

function add (item,index)
{
if (item.substr(0,1) != "1")
{
bilder = bilder + '<img id="'+item+'" src="img/unit/'+item.substr(0,3)+'.png" height="20px"> ';
}


else if (item.substr(0,1) == "1")
{


var counter = 0;
var numID_copy = numID.slice();


for(i=0;i<numID_copy.length;i++)
{
if (item.substr(0,3) == ID_copy.substr(0,3))
{
count++;

if(item != numID_copy)
{
numID_copy.splice(i,1);
}

}
}

bilder = bilder + '<img id="'+item+'" src="img/unit/'+item.substr(0,3)+'.png" height="20px"> ';

}

document.getElementById("truppe_name").innerHTML = bilder;
}
[/src]
 
Ich würde das Problem in 2 Schritte unterteilen und erst eine saubere Datenstruktur zusammenbauen, über die anschließend iteriert werden kann, um den HTML-Code für die Bilder zu generieren:

[src=javascript]var nums = '1311673;1116253;1115264;1117243;3328463'.split(';')
var groups = {};

nums.forEach(function(num){
if(num.substr(0, 1) == '1'){
var group = num.substr(0, 3);
if(!groups[group]){
groups[group] = {id: num, count: 0};
}
groups[group].count++;
}
});[/src]

[kw]groups[/kw] sieht anschließend so aus:

[src=javascript]{
111: {id: "1116253", count: 3}
131: {id: "1311673", count: 1}
}[/src]
 
Zuletzt bearbeitet:
Ja und nein "Num_id_copy" ist übrigens laut dem Code aus dem Startpost unbekannt:

Hier wäre es einfacher, die Anzahl von "ununterbrochen" Einsen (1) - aus dem Quellstring zu zählen.

Also das Substring bzw. String.charAt[index] == "1" nur immer eine* Position auswertet und daran entscheidet. (*Das sollte dann allerdings fortlaufend den String überprüfen, also bei Position/Index 0 anfangen und hochzählen und notieren).

Ich finde übrigens das Konstrukt, eine Funktion aufzurufen, im Gegensatz zu einer anonymen Funktion eleganter. Weil der Code wartbarer wird bzw. bleibt.

Edit2:

Eigentlich könnte man auch ein Regex nehmen und nur die "einsen" matchen die in dem String vorkommen. Die Anzahl der Treffer wäre schon das Ergebnis, wobei dann allerdings die Ordnung im String nicht bekannt wäre... aber so als zweite Idee.
 
Zuletzt bearbeitet:
bin da bei Split, regex wäre da sicher wesentlich schöner und effizienter.

Sowas hier, das kannst du direkt auf deinen variable numid anwenden:

[src=javascript]count_OneInFront : function(text) {
return (text.match(/[1]{1}[0-9]{6}/g).length);
}

count_TribbleOne : function(text) {
return (text.match(/[1]{3}[0-9]{4}/g).length ;
}[/src]
 
Dein Regex ist glaube ich nicht ganz richtig, weil du bei deinem Match auch die Zahlen 0-9 einbeziehst. die darauf folgend sollen, mit bis zu 6 oder 4 mehr Zeichen, das ist zwar eine validierung, sprengt aber das geforderte ;)

Und warum das "global" Flag? - wir wollen nur einen Match, Beispiel wie es sein könnte:

[src=javascript]"11123415".match(/[1]/g).length; // = 4, zaehlt alle einsen in dem String weil global durch das Flag - g
"11123415".match(/[1]*/) // = Array ["111"], auch weil nicht 'g'lobal
"11123415".match(/[1]*/)[0].length // = "111".length == 3 (3 führende einsen) TREFFER!, global würde hier die ersten 3 und die 1 zwischen vier und fünf matchen, wir wollen aber nur einen Match!
"411123415".match(/[1]*/)[0].length // == 0 (0 führende einsen, weil 4 am Anfang steht)[/src]
 
Er möchte ja nicht die Anzahl der 1-en zählen sondern alle 7-Stelligen Zahlen nach einem gewissen Muster.
Also Validiere ich per regex auf das gesuchte Muster und zähle die Ergebnisse.

Bei der Eingabe von "1311673;1116253;1115264;1117243;3328463" zählt dann die erste Funktion 4, die zweite Funktion 3.
Ohne global würden beide 1 zählen.

Wenn ich *eine* Zahl übergebe muss ich ja wieder splitten und iterieren - das ist ja das was man sich dadurch sparen kann.
 
Ah, ich hatte das Problem nicht verstanden um ehrlich zu sein, ich hab nur geglaubt ich hätte es verstanden. :o

Dann macht das wie es beschreibt, wohl noch am meisten Sinn. Aber ohne anynoyme Funktion dann bitte! ;)
Also Gruppen aus den ersten drei Ziffern zu bilden, wenn die erste Stelle eine 1 ist und diese Liste am Ende auszuwerten.

Hatte total überlesen das Nietal die ersten 3 Positionen (also nicht nur "111") sonder auch "131" oder ähnliches berücksichtigen lassen will bzw. auch nach gleichen Mustern innerhalb der ersten 3 Ziffern sucht.... die am häufigsten auftreten / sich überschneiden.

Wieder einmal vorschnell gehandelt... :o

Dann ist das mit dem Regex wirklich nicht sinnvoll, jedenfalls nicht so, wie ich es mir gedacht habe... wie naiv :D


Edit: Aber drfuture, deine Idee haut dann auch nicht ganz hin ;)

Die erste "If" Abfrage muss ja nur schauen ob die erste Ziffer eine 1 ist... um valide zu sein. Die zweite sucht dann alle Verbindungen mit 1xx raus und zählt diese durch... also eigentlich das was hier schon als erste vorgeschlagen wurde ;)
 
Zuletzt bearbeitet:
hmmm das es um Gruppen von Zahlen geht habe ich so auch nicht verstanden... bin gespannt was der TS so dazu sagt *Fg*
 
Zurück
Oben