是否可以遍历关联数组中的所有元素?我想使用循环来迭代关联数组中的所有值。在我的一生中,我找不到关联数组的迭代器函数。 如果关联数组中的所有值不是预先知道的键,那么是否根本不可能遍历它们?
在我的关联数组中,键是字符串,值是列表。我需要迭代整个关联数组,并对于每个键,从值中读取一些内容。
这是我的(不完整的)脚本。我对某些编程语言是半老手,但对 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 脚本语言中关联数组的等效项是什么?