Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Ich möchte eine Schleife verwenden, um alle Werte in einem assoziativen Array zu durchlaufen.Beim besten Willen kann ich die Interatorfunktion für assoziative Arrays nicht finden. Ist es einfach unmöglich, alle Werte in einem assoziativen Array zu durchlaufen, wenn sie sich nicht an vorbekannten Schlüsseln befinden?!
In meinem assoziativen Array sind die Schlüssel Zeichenfolgen und die Werte Listen.Ich muss das gesamte assoziative Array durchlaufen und für jeden Schlüssel etwas aus dem Wert lesen.
Dies ist mein (unvollständiges) Skript.Ich bin ein Halbveteran in einigen Programmiersprachen, aber im Umgang mit JMP-Skripten bin ich ein Neuling.
Wo ich Kommentare in /* */ einfüge, ist Code, von dem ich nicht weiß, wie man ihn macht.Ich stecke unten bei /*For all parts in lastTests*/ fest, obwohl ich nicht weiß, ob der Rest meines Skripts funktioniert, da ich noch nicht versucht habe, irgendetwas davon auszuführen.
Übrigens enthält das JMP-Skripthandbuch einen sehr kurzen Abschnitt über assoziative Arrays und erklärt Ihnen nicht, wie Sie Elemente innerhalb eines assoziativen Arrays durchlaufen 
Bitte helfen Sie!
dt = Current Data Table();
lastTests = Associative Array();
For Each Row (
partKey = Char(:Name("214:ReadOTP:OTP_Row_40[1]") + 256*:Name("215:ReadOTP:OTP_Row_41[1]") + 256*256*:Name("223:ReadOTP:OTP_Row_49[1]") + 256*256*256*:Name("224:ReadOTP:OTP_Row_4a[1]") + 256*256*256*256*:Name("123:LOG_SETPOINT_SPEA:SPEA_Setpoint[1]"));
rowValue = {:Name("start_t"), :Name("part_id"), Row()};
If (Is List(lastTests[partKey]) == 1,
If ( rowValue[1] > lastTests[partKey][1], //if start_t is later
lastTests[partKey] = rowValue,
//else if
(rowValue[1] == lastTests[partKey][1]) & (rowValue[2] > lastTests[partKey][2]), //if start_t is the same but part_id is larger
lastTests[partKey] = rowValue;
),
//else
lastTests[partKey] = rowValue;
);
);
listOfRowsToSelect = {};
/*For all parts in lastTests*/(
selectedPart = /*get present item*/;
Insert Into(listOfRowsToSelect, selectedPart[3]);
);
dt << Select Rows( listOfRowsToSelect );
/*Invert Selection*/;
/*Hide and Exclude selected rows*/;
dt << Clear Select;
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Immer noch schwierig.Verwenden evallist() um es in einem Schritt zu tun.Auch, anstatt zu sagen if (hatWert == 1, Sag nur wenn (Wert hat, .Eine positive ganze Zahl ist in JSL wahr, 0 ist falsch.Hier sind einige Möglichkeiten, das zu tun, was Sie wollen.Die eine Methode durchläuft alle Zeilen explizit, die andere verwendet sie Für jede Reihe .
dt = open("$sample_data\Big Class.jmp");
for (i = 1, i <= nrows(dt), i++,
rowvalue = evallist({column(dt, "age")[i], column(dt, "height")[i], i});
print(rowvalue);
);
current data table(dt);
for each row(
rowvalue = evallist({as column(dt, "age"), as column(dt, "height"), row()});
// This works too
// rowvalue = evallist({:name("age"), :name("height"), row()});
print(rowvalue);
);Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Ich glaube, ich habe es endlich zum Laufen gebracht.Ich wünschte, ich könnte einer Liste in derselben Zeile, in der ich sie erstellt habe, Werte zuweisen und alle Befehle zum Einfügen in entfernen.Muss ich das wirklich tun:
rowValue = {};
Insert Into(rowValue, :Name("start_t"));
Insert Into(rowValue, :Name("part_id"));
Insert Into(rowValue, Row());
Wann möchte ich das wirklich tun?
rowValue = {:Name("start_t"), :Name("part_id"), Row()};Bei letzterem ist der Wert der Liste an Index 3 jedoch buchstäblich nur der Text „Row()“!Sollte es nicht die Funktion Row() ausführen und den Wert zurückgeben?!
Gibt es ein bekanntes Problem in Windows 10, bei dem das Skriptfenster unglaublich träge ist?
Wie auch immer, dies ist das Skript in der Form, in der es endlich zu funktionieren scheint (muss vollständig überprüft werden):
dt = Current Data Table();
dt << Clear Select;
lastTests = Associative Array();
//For(i = 1, i <= N Rows(dt), i++,
For Each Row (
//Row() = i;
partKey = Char(:Name("214:ReadOTP:OTP_Row_40[1]") + 256*:Name("215:ReadOTP:OTP_Row_41[1]") + 256*256*:Name("223:ReadOTP:OTP_Row_49[1]") + 256*256*256*:Name("224:ReadOTP:OTP_Row_4a[1]") + 256*256*256*256*Abs(:Name("123:LOG_SETPOINT_SPEA:SPEA_Setpoint[1]")));
rowValue = {};
Insert Into(rowValue, :Name("start_t"));
Insert Into(rowValue, :Name("part_id"));
Insert Into(rowValue, Row());
//rowValue = {:Name("start_t"), :Name("part_id"), i};
hasValue = 0;
try(
junk = lastTests[partKey];
hasValue = 1;
);
If ( hasValue == 1,
If ( rowValue[1] > lastTests[partKey][1], //if start_t is later
lastTests[partKey] = rowValue,
//else if
(rowValue[1] == lastTests[partKey][1]) & (rowValue[2] > lastTests[partKey][2]), //if start_t is the same but part_id is larger
lastTests[partKey] = rowValue;
),
//else
lastTests[partKey] = rowValue;
);
);
listOfRowsToSelect = {};
listOfVals = lastTests << Get Values;
//Show(N Items(listOfVals));
For(i = 1, i <= N Items(listOfVals), i++,
Insert Into(listOfRowsToSelect, listOfVals[i][3]);
//Print(listOfVals[i][3]);
);
dt << Select Rows( listOfRowsToSelect );
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Cool. Ich hatte gehofft, dass JMP so etwas wie Try hätte.Ich werde es versuchen.
und vergleiche seine Ausführungszeit mit „Contains“, wenn ich die Zeit später erhalte.Vielen Dank für die Hilfe.Ich werde Updates veröffentlichen, sobald ich sie habe.
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Sie könnten einen einfachen Test für den Schlüsselwert in a einbinden versuchen() Abschnitt.Ich bin mir nicht sicher, ob die Leistung vs enthält .
found = 0;
try(
b = aa["junk"]; // This key is not in the associative array
found = 1;
);
show(found); // Returns 1 if found, 0 if not found. 1 is the same as TRUE, 0 is the same as FALSE
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Wissen Sie also mit Sicherheit, dass es keine Möglichkeit gibt, ein assoziatives Array zu testen, um festzustellen, ob ein Schlüssel vorhanden ist, ohne die Funktion „Schlüssel abrufen“ zu verwenden? Erzeugt ein assoziatives Array immer einen Fehler, wenn Sie versuchen, auf einen Schlüssel zuzugreifen, der noch nicht existiert?
12 ms werden sehr problematisch sein, das ist eine enorm lange Zeit, um festzustellen, ob ein Wert für einen bestimmten Schlüssel vorhanden ist. Ich bin mir ziemlich sicher, dass andere Skriptsprachen dies in Mikrosekunden-Zeitskalen tun. Ich weiß, dass Lua es unglaublich schnell macht (im Vergleich zu mindestens 12 ms). Wenn ich es mit einer Datentabelle mit 300.000 Zeilen zu tun habe, könnten das tatsächlich etwa 300.000 Schlüssel sein. Die Ausführungszeit könnte sich also auf (300k/20k)*12 ms = 180 ms erhöhen. ABER das müsste dann etwa 300.000 Mal ausgeführt werden, sodass die Gesamtausführungszeit 15 Stunden beträgt (180 ms * 3e5 = 15 Stunden). Tatsächlich wäre es wahrscheinlich etwa die Hälfte davon, da das assoziative Array mit der Laufzeit der Schleife wachsen würde. Aber 7,5 Stunden sind immer noch zu lang.
Allerdings ist es vielleicht nicht die Funktion „Contains“, die den Großteil der Ausführungszeit (innerhalb der 12 ms) in Anspruch nimmt, sondern die Funktion „Get Keys“?In meinem Skript müsste ich Get Keys nicht einmal ausführen überhaupt wenn ich einfach (parallel) eine separate Liste von Schlüsseln behalte, die ich dem assoziativen Array hinzugefügt habe.
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Verstanden.Ich habe einen Test mit einem assoziativen Array mit 20.000 Schlüsseln durchgeführt.Ich habe eine enthält-Suche verwendet, um nach jedem der 20.000 Schlüssel zu suchen. hat 12 Sekunden gedauert.Die Suche nach einem einzelnen Schlüssel dauert den Bruchteil einer Sekunde.
// Look for one key
start = hp time();
zlist = aa << getkeys(); // Contains 20,000 keys
a = "xyz9999";
flag = contains(zlist, a);
end = hp time();
show((end - start)/1000000);
// .012 seconds
// Search for all keys using CONTAINS
start = hp time();
for (i = 1, i <= nitems(xlist), i++, // xlist contains the keys in order of creation
x = xlist[i];
b = contains(zlist, x); // zlist comes from getkeys and is not in order of creation
);
end = hp time();
show((end - start)/1000000);
// 12.2 seconds
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Ja, aber dieses Skript und seine Ableitungen, die ich erstellen möchte, müssen eine Datentabelle mit weit über dreihunderttausend Zeilen und jeweils Hunderten von Spalten bearbeiten (wenn mein Computer das nicht bewältigen kann, wenn nicht, dann werde ich es tun). um es etwas aufzuteilen, aber die Tabellengröße für jedes Datenbankfragment wird immer noch RIESIG sein).
So ist es von entscheidender Bedeutung diesen Code so zu optimieren, dass er möglichst effizient läuft.Führen Sie „Get Keys“ für das assoziative Array aus und durchsuchen Sie dann die riesige Liste mit Zehntausenden oder Hunderttausenden Einträgen einfach Zu sehen, ob die zurückgegebene Liste einen Wert enthält, scheint SCHRECKLICH ineffizient zu sein, wenn ich nur prüfen muss, ob lastTests[partKey] ein Wert zugewiesen ist oder nicht!
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Der getkeys Die Methode gibt alle Schlüssel für ein assoziatives Array zurück.
aa = associative array();
aa["One"] = {1, 2, 3};
aa["Two"] = {"a", "b", "c"};
key_list = aa << getkeys();
// Results shown in the log:
{"One", "Two"}Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Ich habe auch die Funktion „Ist leer“ ausprobiert (wobei ich im Vergleich auch die 1 in eine 0 umgewandelt habe), und sie hat mir den gleichen Fehler angezeigt.
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Danke Mark, meiner Meinung nach sollte es so funktionieren und es ist dasselbe wie ähnliche Datenstrukturen in anderen Sprachen.
Wie testet man, ob einem assoziativen Array ein Wert einem bestimmten Schlüssel zugewiesen ist? Da ich Listen bestimmte „Char“-Schlüsselwerte (das Gleiche wie eine Zeichenfolge?) zuweise, habe ich zuerst die Funktion „Ist Liste“ ausprobiert, aber sie hat mir einen Fehler angezeigt. Das war mein Drehbuch:
dt = Current Data Table();
lastTests = Associative Array();
For Each Row (
partKey = Char(:Name("214:ReadOTP:OTP_Row_40[1]") + 256*:Name("215:ReadOTP:OTP_Row_41[1]") + 256*256*:Name("223:ReadOTP:OTP_Row_49[1]") + 256*256*256*:Name("224:ReadOTP:OTP_Row_4a[1]") + 256*256*256*256*Abs(:Name("123:LOG_SETPOINT_SPEA:SPEA_Setpoint[1]")));
rowValue = {:Name("start_t"), :Name("part_id"), Row()};
If (Is List(lastTests[partKey]) == 1,
If ( rowValue[1] > lastTests[partKey][1], //if start_t is later
lastTests[partKey] = rowValue,
//else if
(rowValue[1] == lastTests[partKey][1]) & (rowValue[2] > lastTests[partKey][2]), //if start_t is the same but part_id is larger
lastTests[partKey] = rowValue;
),
//else
lastTests[partKey] = rowValue;
);
);
listOfRowsToSelect = {};
listOfVals = lastTests << Get Values;
For(i = 1, i <= nrows(listOfVals), i++,
Insert Into(listOfRowsToSelect, listOfVals[i][3]);
);
dt << Select Rows( listOfRowsToSelect );Und das ist der Fehler, den ich im Protokoll sehe:
subscripted key not in map["192344950106"]{1} in access or evaluation of 'partKey' , partKey/*###*/
In the following script, error marked by /*###*/
dt = Current Data Table();
lastTests = Associative Array();
For Each Row(
partKey = Char(
:Name( "214:ReadOTP:OTP_Row_40[1]" ) + 256 *
:Name( "215:ReadOTP:OTP_Row_41[1]" ) + 256 * 256 *
:Name( "223:ReadOTP:OTP_Row_49[1]" ) + 256 * 256 * 256 *
:Name( "224:ReadOTP:OTP_Row_4a[1]" ) + 256 * 256 * 256 * 256 *
Abs( :Name( "123:LOG_SETPOINT_SPEA:SPEA_Setpoint[1]" ) )
);
rowValue = {:start_t, :part_id, Row()};
If( Is List( lastTests[partKey/*###*/] ) == 1,
If(
rowValue[1] > lastTests[partKey][1], lastTests[partKey] = rowValue,
rowValue[1] == lastTests[partKey][1] & rowValue[2] > lastTests[partKey][
2], lastTests[partKey] = rowValue
),
lastTests[partKey] = rowValue
);
);
listOfRowsToSelect = {};
listOfVals = lastTests << Get Values;
For( i = 1, i <= N Rows( listOfVals ), i++,
Insert Into( listOfRowsToSelect, listOfVals[i][3] )
);
dt << Select Rows( listOfRowsToSelect );
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Beachten Sie, dass der Inhalt des assoziativen Arrays nicht geordnet ist. Die Indizierung ist out. Aus diesem Grund durchlaufen die ersten und nächsten Nachrichten das Array. Die Verwendung der Get Values-Nachricht gibt ein geordnetes Ergebnis zurück, die Inhalte sind jedoch nicht unbedingt in dieser Reihenfolge.
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Danke schön!Ich wusste nichts über den Hilfe->Skriptindex!
In meinem Fall sieht es so aus, als müsste ich die Funktion „Werte abrufen“ verwenden (die Schlüssel benötige ich nicht).
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?Um die für ein assoziatives Array verfügbaren Funktionen und Nachrichten zu finden, gehen Sie zu
Hilfe==>Skriptindex==>Assoziatives Array
Dort finden Sie mehrere Möglichkeiten, die Schlüssel oder Werte zu durchlaufen, indem Sie sie in eine Liste abrufen und dann eine For()-Schleife usw. verwenden. Nachfolgend finden Sie ein Beispiel, das direkt aus den Beispielen im Skriptindex mit „First“ und „First“ stammt „Weiter“, um ein assoziatives Array zu durchlaufen
Names Default To Here( 1 );
Local(
{aa = [1 => "bun",
2 => "shoe",
3 => "tree",
4 => "door"], x, words = ""},
x = aa << First;
While( !Is Empty( x ),
words = words || aa[x];
x = aa << Next( x );
);
words;
);
Außerdem gibt es ab Seite 207 im JSL Scripting Guide mehrere Seiten mit Dokumentation zum Erstellen und Verwenden assoziativer Arrays in JMP
Hilfe==>Bücher==>Skripthandbuch
Betreff: Ist es möglich, alle Elemente in einem assoziativen Array zu durchlaufen?So durchlaufen Sie beispielsweise alle Werte in einer Tabelle (mit dem Namen „t“) in Lua, einer gängigen Skriptsprache:
für Schlüssel, Wert in Paaren (t) tun
Ende
Was ist das Äquivalent in der JMP-Skriptsprache für assoziative Arrays?