연관 배열의 모든 요소를 반복할 수 있습니까?루프를 사용하여 연관 배열의 모든 값을 반복하고 싶습니다.내 인생에서 연관 배열에 대한 인터레이터 기능을 찾을 수 없습니다. 미리 알려진 키가 아닌 경우 연관 배열의 모든 값을 단계별로 실행하는 것이 불가능합니까?!
내 연관 배열에서 키는 문자열이고 값은 목록입니다.전체 연관 배열을 반복하고 각 키에 대해 값에서 무언가를 읽어야 합니다.
이것은 내 (불완전한) 스크립트입니다.저는 일부 프로그래밍 언어의 반 베테랑이지만 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;
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?여전히 까다롭습니다.사용 평가자() 한 단계로 할 수 있습니다.또한, 말하는 대신 if (값 == 1, 그냥 말해 if (가치, .양의 정수는 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);
);Re: 연관 배열의 모든 요소를 반복할 수 있습니까?드디어 일하게 된 것 같아요.목록을 구성한 동일한 줄에서 목록에 값을 할당하고 모든 삽입 명령을 제거할 수 있으면 좋겠습니다.정말 이렇게 해야 합니까:
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 );
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?시원한. 저는 JMP에 Try와 같은 기능이 있기를 바랐습니다.시도해볼께요 시도해보세요
나중에 시간을 얻을 때 실행 시간과 포함을 비교합니다.도움을 주셔서 대단히 감사합니다.업데이트가 있으면 게시하겠습니다.
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?키 값에 대한 간단한 테스트를 노력하다() 부분.성능 대비 확실하지 않음 포함 .
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
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?그렇다면 키 가져오기 기능을 사용하지 않고 키가 존재하는지 확인하기 위해 연관 배열을 테스트할 방법이 없다는 것을 확실히 알고 계십니까? 아직 존재하지 않는 키에 액세스하려고 하면 연관 배열에서 항상 오류가 발생합니까?
12ms는 매우 문제가 될 것입니다. 특정 키에 값이 존재하는지 확인하는 데 엄청나게 긴 시간입니다. 저는 다른 스크립팅 언어가 마이크로초 단위로 이 작업을 수행한다고 확신합니다. 나는 Lua가 엄청나게 빠르다는 것을 알고 있습니다(적어도 12ms에 비해). 300k 행의 데이터 테이블을 다루는 경우 실제로는 약 300k 키가 될 수 있습니다. 따라서 실행 시간은 (300k/20k)*12ms = 180ms로 증가할 수 있습니다. 그러나 그러면 약 30만 번 실행해야 하므로 총 실행 시간은 15시간(180ms * 3e5 = 15시간)이 됩니다. 실제로 루프가 실행됨에 따라 연관 배열이 증가하기 때문에 아마도 그 절반 정도일 것입니다. 하지만 7.5시간은 여전히 너무 길다.
그러나 대부분의 실행 시간(12ms 이내)을 잡아먹는 것은 Contains 함수가 아니라 Get Keys 함수일까요?내 스크립트에서는 Get Keys를 실행할 필요조차 없습니다. 조금도 연관 배열에 추가한 별도의 키 목록을 (병렬로) 유지하는 경우.
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?이해했다.20,000개의 키가 있는 연관 배열로 테스트를 수행했습니다.20,000개의 키 각각을 찾기 위해 포함 검색을 사용했습니다. 12초 걸렸다.개별 키를 찾는 데는 몇 분의 1초도 걸리지 않습니다.
// 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
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?예, 하지만 이 스크립트와 그 파생물은 각각 수백 개의 열이 있는 30만 개 이상의 행이 있는 데이터 테이블에서 작동해야 합니다(내 컴퓨터가 처리할 수 없는 경우, 그렇지 않은 경우 일부를 분할하지만 각 데이터베이스 조각의 테이블 크기는 여전히 거대합니다).
그래서, 그것은 비판적으로 중요한 가능한 한 효율적으로 실행되도록 이 코드를 최적화합니다.연관 배열에서 Get Keys를 실행한 다음 수만 또는 수십만 개의 항목이 있는 방대한 목록을 검색합니다. 간단히 반환된 목록에 값이 포함되어 있는지 확인하려면 lastTests[partKey]에 할당된 값이 있는지 확인하기만 하면 됩니다.
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?그만큼 getkeys 메서드는 연관 배열의 모든 키를 반환합니다.
aa = associative array();
aa["One"] = {1, 2, 3};
aa["Two"] = {"a", "b", "c"};
key_list = aa << getkeys();
// Results shown in the log:
{"One", "Two"}Re: 연관 배열의 모든 요소를 반복할 수 있습니까?또한 Is Empty 함수(비교에서도 1을 0으로 전환)를 시도했는데 동일한 오류가 발생했습니다.
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?감사합니다 Mark, 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 );
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?연관 배열의 내용에는 순서가 없다는 점에 유의하십시오. 인덱싱이 종료되었습니다. 이것이 First 및 Next 메시지가 배열 전체를 반복하는 이유입니다. 값 가져오기 메시지를 사용하면 순서가 지정된 결과가 반환되지만 내용이 반드시 이 순서로 되어 있지는 않습니다.
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?감사합니다!Help->Scripting Index에 대해 몰랐습니다!
제 경우에는 값 가져오기 기능을 사용해야 하는 것 같습니다(키가 필요하지 않음).
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?연관 배열에서 사용할 수 있는 기능과 메시지를 찾으려면 다음으로 이동하십시오.
도움말==>스크립팅 인덱스==>연관 배열
여기에서 키 또는 값을 목록으로 가져온 다음 For() 루프 등을 사용하여 키 또는 값을 반복하는 여러 방법을 찾을 수 있습니다. 아래는 "First" 및 연관 배열을 반복하는 "다음"
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에서 연관 배열을 만들고 사용하는 방법에 대한 여러 페이지의 설명서가 있습니다.
도움말==>도서==>스크립팅 가이드
Re: 연관 배열의 모든 요소를 반복할 수 있습니까?예를 들어, 다음은 일반적인 스크립팅 언어인 Lua에서 테이블("t"라는 이름)의 모든 값을 반복하는 방법입니다.
키의 경우 쌍으로 된 val(t) do
<물건>
끝
JMP 스크립팅 언어에서 연관 배열에 해당하는 것은 무엇입니까?