JSL 程式設計挑戰:將 Y 和 N 的字串轉換為 1 和 0 的矩陣,然後再轉換回來嗨,JSL 程式設計師,
作為較大應用程式的一部分,我遇到了一個小問題,我想與您分享它,看看是否有辦法做得更好/更流暢。
基本上我有一個 1 和 0 的向量(即 [1, 1, 0, 0, 1]),我需要將其轉換為 Y 和 N 的字串(即“YYNNY”)。然後我需要做相反的事情,即將 Y 和 N 的字串轉換回 1 和 0 的向量。
這是我的快速而骯髒的功能 - 讓我們看看你是否能想出一些超出我微弱腦力的東西!
// Convert a vector of 1s and 0s to a string with no separators
matrix_10_to_yn = function({matrix_10}, {default local},
yn_txt = "";
if (nrows(matrix_10) > 0,
// Strip out square brackets and commas
yn_txt = substitute(char(matrix_10), "[", "", "]", "", ", ", "");
// Now convert 1s to Y and 0s to N
yn_txt = substitute(yn_txt, "1", "Y", "0", "N");
);
yn_txt;
);
// Convert a YN string with no separators to a vector of 1s and 0s
yn_to_matrix_10 = function({yn_txt}, {default local},
n = length(yn_txt);
matrix_10 = j(n, 1, 0);
for (i = 1, i <= n, i++,
if (substr(yn_txt, i, 1) == "Y",
matrix_10[i] = 1;
);
);
matrix_10;
);
<BR />// Test thing out
a = yn_to_matrix_10("YYYNNNN"); show(a);
b = matrix_10_to_yn(a); show(b);
c = yn_to_matrix_10(""); show(c);
d = matrix_10_to_yn(c); show(d);回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來如此酷的解決方案。我不敢相信有許多方法可以用來解決這個相對簡單的問題。再次感謝大家。
回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來這些都是非常酷的解決方案。 PMROZ 指出我誤讀了 secanrio 是從清單開始。 他要求我提供修改後的解決方案。下面將 YN 的列表或字串轉換為 10 的向量,並將 10 的向量轉換為 YN 的字串。
為了與我之前的文章保持一致,我只是使用一個空字串分隔符,使用words()函數將字串轉換為列表。
exmat = J(25,1, RandomInteger(0,1));
exlst = Insert({}, {"Y", "N"}[2-exmat]);
exstr = ConcatItems(Insert({}, {"Y", "N"}[2-exmat]), "");
convert_yn = Function({usr}, {rslt=empty(), ynList ={"Y","N"} },
if(IsMatrix(usr),
rslt = ConcatItems(insert({},ynList[2-usr]),"")
, //else
IsList(usr),
rslt = J(nitems(usr),1, 1);
rslt[loc(usr,"N")]=0
, //else
IsString(usr),
rslt = J(length(Trim(usr)),1,1);
rslt[loc(words(usr,""),"N")]=0
); //end if
rslt
); //end Function
show(exmat, convert_yn(exmat), exlst, convert_yn(exlst), exstr, convert_yn(exstr) );回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來我在大多數專案中使用通用的“maply”函數,所以通常我只需要最後兩行:
Names Default to here(1);
// Utility function to make for loops, combo 'map' and 'apply'
// this is a 'fake' map/apply function because it allows side
// effects (like apply) and it also returns a value (like map)
mapply = function( {x, foo, arg1 = "__missing", arg2 = "__missing"}, { i, r = {}, x, foo, arg1, arg2, arg1missing, arg2missing },
if( N Items( x ) < 1,
return({}), //empty list supplied, return an empty list
for( i = 1, i <= N Items(x), i++,
arg1missing = 0; arg2missing = 0;
If( type(arg1) == "String", If( arg1 == "__missing", arg1missing = 1 ) );
If( type(arg2) == "String", If( arg2 == "__missing", arg2missing = 1 ) );
if(
arg1missing == 1,
r = Insert( r, foo( x[i] ) ),
arg2missing == 1,
r = Insert( r, foo( x[i], arg1 ) ),
r = Insert( r, foo( x[i], arg1, arg2 ) )
)
)
);
return(r);
);
// Solution:
str = "YYYNNNNYYNY";
(numbers = mapply( words(str,""), function( {x}, if( x=="Y", 1, 0) ) ) )
mapply( as list(numbers), function( {x}, if( x==1,"Y", "N") ) )回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來@pmroz ,
這是我對此的看法/嘗試。 感謝您提供這個有趣的挑戰。 我知道我正在使用一個循環,我不知道它是否可以在大型矩陣上很好地擴展,但我認為,社區中的其他一些人可以想出更快的方法。
Clear Log(); Clear Globals();
ex = Associative Array({1,0} ,{"Y", "N"});
Test = [1,0, 1, 1, 1, 0, 0, 1, 0, 1];
Res = {};
for(i = 1, i <= N Rows(Test), i++,
Insert Into(Res, ex << Get Value(Test[i]));
);
Show(Res);
回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來現在我需要研究 design() 函數!
回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來哇,這些太棒了。謝謝大家!
回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來哎呀,我沒有看到克雷格的回應……我認為他的版本更好。
回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來您可以使用 Char to Blob 和 Blob to Matrix 在一行中完成字串到矩陣的轉換。 我的貢獻:
names default to here(1);
a=[1,0, 1, 1, 1, 0, 0, 1, 0, 1];
b="YNYYYNNYNY";
f_YNString_to_IndicatorVector=Function({s},
blob to matrix(char to blob(d),"int", 1, "little", 1)==89;
);
f_IndicatorVector_to_YNString=Function({v},{vv},
vv=As List(v);
vv[loc(v)]="Y";
vv[loc(!v)]="N";
concat items(vv,"");
);
show(a);
show(b);
Show(f_YNString_to_IndicatorVector(b));
Show(f_IndicatorVector_to_YNString(a));
Show(f_IndicatorVector_to_YNString(f_YNString_to_IndicatorVector(b)));
回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來
如果沒有一些額外的努力,這不會擴展到三個值或缺失/錯誤值。 它轉換 string--blob--matrix 並使用矩陣中 ASCII 字元的數量進行 Y 和 N 檢測。 BlobToMatrix 和 MatrixToBlob 函式被告知使用 1 位元組小端整數。 對於 1 位元組數字來說,字節序並不重要,大字節序也同樣適用。 它確實取決於具有一位元組表示的字元。
source = "YYNNYQ";
// if you are uncomfortable with hard coded constants...
Yvalue = Blob To Matrix( Char To Blob( "Y" ), "int", 1, "little" )[1]; // 89
Nvalue = Blob To Matrix( Char To Blob( "N" ), "int", 1, "little" )[1]; // 78
// forward
numbers = Blob To Matrix( Char To Blob( source ), "int", 1, "little" ) == Yvalue;
// reverse
string = Blob To Char( Matrix To Blob( Nvalue + numbers * (Yvalue - Nvalue), "int", 1, "little" ) );
// display
Show( source, numbers, string );
來源=“YYNNYQ”;
數字 = [1, 1, 0, 0, 1, 0];
字串=“YYNNYN”;
回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來其他!!
Names Default to here(1);
yto1 = function({str},
{DEFAULT LOCAL},
list = words(str, "");
design(list, {"Y"});
);
oneToY = function({mat},
list = substitute(as list(mat), 1, "Y", 0, "N");
Concat items(list, "");
);
str = "YYYNNNNYYNY";
nums = yto1(str);
show(nums);
str2 = oneToY(nums);
show(str2, str2==str);回覆:JSL 程式設計挑戰:從 Y 和 N 字串轉換為 1 和 0 矩陣,然後再轉換回來無論什麼有效,都有效!這是一種替代方案。
exmat = J(25,1, RandomInteger(0,1));
exlst = Insert({}, {"Y", "N"}[2-exmat]);
convert_yn = Function({usr}, {rslt, ynList ={"Y","N"} },
if(IsMatrix(usr),
rslt = insert({},ynList[2-usr])
, //else
rslt = J(nitems(usr),1, 1);
rslt[loc(usr,"N")]=0
); //end if
rslt
); //end Function
show(exmat, convert_yn(exmat), exlst, convert_yn(exlst));