是否可以遍歷關聯數組中的所有元素?我想使用循環來迭代關聯數組中的所有值。在我的一生中,我找不到關聯數組的迭代器函數。 如果關聯數組中的所有值不是預先知道的鍵,那麼是否根本不可能遍歷它們?
在我的關聯數組中,鍵是字符串,值是列表。我需要迭代整個關聯數組,並對於每個鍵,從值中讀取一些內容。
這是我的(不完整的)腳本。我對某些編程語言是半老手,但對 JMP 腳本卻是菜鳥。
我在 /* */ 中添加註釋的地方是有我不知道該怎麼做的代碼的地方。我被困在底部附近的 /*For all parts in lastTests*/ 處,儘管我不知道腳本的其餘部分是否有效,因為我還沒有嘗試運行其中的任何一個。
順便說一下,JMP 腳本指南有一個關於關聯數組的非常簡短的部分,它沒有告訴您如何迭代關聯數組中的元素:(
請幫忙!
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;
回复:是否可以遍歷關聯數組中的所有元素?還是很棘手。使用評估列表()一步完成。另外,而不是說if (hasvalue == 1,說啊如果(有值, 。JSL 中正整數為 True,0 為 false。這裡有一些方法可以做你想做的事。一種方法顯式循環所有行,另一種方法使用對於每一行。
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);
);回复:是否可以遍歷關聯數組中的所有元素?我想我終於成功了。我希望我可以在構建列表的同一行中將值分配給列表,並擺脫所有“插入”命令。我真的必須這樣做嗎:
rowValue = {};
Insert Into(rowValue, :Name("start_t"));
Insert Into(rowValue, :Name("part_id"));
Insert Into(rowValue, Row());
當我真的只想這樣做時?
rowValue = {:Name("start_t"), :Name("part_id"), Row()};然而,對於後者,索引 3 處的列表的值實際上只是文本“Row()”!難道它不應該運行 Row() 函數並返回值嗎?!
Windows 10 中是否存在腳本窗口極其緩慢的已知問題?
無論如何,這是最終看起來可以工作的腳本形式(需要完全驗證):
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 );
回复:是否可以遍歷關聯數組中的所有元素?涼爽的。 我希望 JMP 有類似 Try 的東西。我會嘗試嘗試:)當我稍後得到時間時,將其執行時間與 Contains 進行比較。非常感謝你的幫助。當我有更新時,我會發布更新。
回复:是否可以遍歷關聯數組中的所有元素?您可以將鍵值的簡單測試包裝在嘗試()部分。不確定性能對比包含。
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
回复:是否可以遍歷關聯數組中的所有元素?那麼,您是否確定不使用 Get Keys 函數就無法測試關聯數組以查看鍵是否存在? 當您嘗試訪問尚不存在的鍵時,關聯數組是否總是生成錯誤?
12 毫秒將會是一個很大的問題,僅僅為了確定某個鍵上是否存在某個值就已經是一個非常長的時間了。 我非常確定其他腳本語言可以在微秒時間尺度內完成此操作;我知道 Lua 的速度快得令人難以置信(至少與 12 毫秒相比)。 如果我處理的是 300k 行的數據表,那麼實際上可能有大約 300k 個鍵。 因此執行時間可能會增加到 (300k/20k)*12 ms = 180 ms。但是,這將需要運行大約 300k 次,因此總執行時間變為 15 小時(180 ms * 3e5 = 15 小時)。 實際上,它可能大約是這個值的一半,因為關聯數組會隨著循環的運行而增長。 但7.5小時還是太長了。
然而,也許不是 Contains 函數消耗了大部分執行時間(12 毫秒內),而是 Get Keys 函數?在我的腳本中,我什至不必運行 Get Keys根本不如果我只是(並行)保留一個單獨的已添加到關聯數組中的鍵列表。
回复:是否可以遍歷關聯數組中的所有元素?明白了。我使用具有 20,000 個鍵的關聯數組進行了測試。我使用包含搜索來查找 20,000 個鍵中的每一個;花了12秒。尋找單個鑰匙只需要幾分之一秒的時間。
// 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
回复:是否可以遍歷關聯數組中的所有元素?是的,但是我計劃製作的這個腳本及其衍生產品需要在一個包含超過三十萬行的數據表上進行操作,每個數據表有數百列(如果我的計算機無法處理這個問題;如果不能,那麼我將有將其分解一些,但每個數據庫片段的表大小仍然很大)。
所以,它是極其重要優化此代碼,使其盡可能高效地運行。在關聯數組上運行 Get Keys,然後搜索包含數万或數十萬條目的龐大列表簡單地當我需要做的就是查看 lastTests[partKey] 是否已分配值時,查看返回的列表是否包含值似乎效率非常低!
回复:是否可以遍歷關聯數組中的所有元素?這獲取密鑰方法返回關聯數組的所有鍵。
aa = associative array();
aa["One"] = {1, 2, 3};
aa["Two"] = {"a", "b", "c"};
key_list = aa << getkeys();
// Results shown in the log:
{"One", "Two"}回复:是否可以遍歷關聯數組中的所有元素?我還嘗試了 Is Empty 函數(在比較中也將 1 切換為 0),它給了我同樣的錯誤。
回复:是否可以遍歷關聯數組中的所有元素?謝謝馬克,IMO,這就是它應該如何運行,並且與其他語言中類似數據結構的運行方式相同。
如何測試關聯數組是否具有分配給特定鍵的值? 由於我將特定的“Char”(與字符串相同?)鍵值分配給列表,因此我首先嘗試了 Is List 函數,但它給了我一個錯誤。 這是我的腳本:
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 );這是我在日誌中看到的錯誤:
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 );
回复:是否可以遍歷關聯數組中的所有元素?請注意,關聯數組的內容沒有順序。 索引已過時。 這就是 First 和 Next 消息迭代數組的原因。 使用獲取值消息返回有序結果,但內容不一定按此順序。
回复:是否可以遍歷關聯數組中的所有元素?謝謝你!我不知道幫助->腳本索引!
在我的例子中,我需要使用“獲取值”功能(我不需要鍵)。
回复:是否可以遍歷關聯數組中的所有元素?要查找關聯數組可用的函數和消息,請轉至
幫助==>腳本索引==>關聯數組
在那裡,您將找到幾種循環鍵或值的方法,方法是將它們檢索到列表中,然後使用For() 循環等。下面是直接取自腳本索引中給出的示例的示例,使用“First ”和“Next”循環關聯數組
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;
);
此外,從《JSL 腳本指南》第 207 頁開始,有幾頁文檔介紹如何在 JMP 中創建和使用關聯數組
幫助==>書籍==>腳本指南
回复:是否可以遍歷關聯數組中的所有元素?舉個例子,下面是如何在 Lua(一種常見的腳本語言)中迭代表(名為“t”)中的所有值:
對於 key,val 成對 (t) 做
<東西>
結尾
JMP 腳本語言中關聯數組的等效項是什麼?