Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversementSalut les programmeurs JSL,
J'ai eu un petit problème dans le cadre d'une application plus vaste et j'ai pensé le partager avec vous, et voir s'il existe un moyen de le faire mieux/plus facilement.
Fondamentalement, j'ai un vecteur de 1 et de 0 (c'est-à-dire [1, 1, 0, 0, 1]) que je dois convertir en une chaîne de Y et de N (c'est-à-dire "YYNNY").Ensuite, je dois faire l'inverse, c'est-à-dire reconvertir une chaîne de Y et de N en un vecteur de 1 et de 0.
Voici mes fonctions rapides et sales - voyons si vous pouvez trouver quelque chose au-delà de ma faible intelligence !
// 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);Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversementDes solutions tellement cool.Je n'arrive pas à croire la variété d'approches utilisées pour résoudre ce problème relativement simple.Merci encore à tous.
Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversementCe sont toutes des solutions très intéressantes. PMROZ a souligné que j'avais mal lu que le secanrio devait commencer par une liste. Il m'a demandé ma solution révisée.Ci-dessous convertit une liste ou une chaîne de YN en un vecteur de 10 et un vecteur de 10 en une chaîne de YN.
Pour être cohérent avec mon message précédent, je viens de convertir la chaîne en liste avec la fonctionwords() en utilisant un délimiteur de chaîne vide.
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) );Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversementJ'utilise une fonction générique 'mapply' dans la plupart des projets, donc normalement je n'aurais besoin que des deux dernières lignes :
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") ) )Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversement@pmroz ,
Voici mon point de vue/tentative à ce sujet. Merci d'avoir proposé ce défi intéressant. Je sais que j'utilise une boucle dont je ne sais pas si elle s'adaptera bien à de grandes matrices, mais j'ai pensé que d'autres membres de la communauté pourraient proposer un moyen plus rapide.
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);
Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversementet maintenant je dois étudier la fonction design() !
Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversementWow, c'est incroyable.Merci a tous!
Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversementOups, je n'ai pas vu la réponse de Craig... sa version est meilleure, je pense.
Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversementvous pouvez effectuer la conversion de chaîne en matrice sur une seule ligne en utilisant Char to Blob et Blob to Matrix. Ma contribution:
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)));
Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversement
Cela ne s'étendra pas à trois valeurs ou à des valeurs manquantes/erreurs sans effort supplémentaire. Il convertit la matrice string--blob-- et effectue la détection Y et N en utilisant le numéro du caractère ASCII dans la matrice. Les fonctions BlobToMatrix et MatrixToBlob doivent utiliser des entiers little-endian de 1 octet. Le caractère boutiste n'est pas critique pour les nombres à 1 octet, big fonctionne tout aussi bien. Cela dépend des caractères ayant des représentations sur un octet.
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 );
source = "AANNNYQ" ;
nombres = [1, 1, 0, 0, 1, 0] ;
chaîne = "AANNYN" ;
Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversementUn autre!!
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);Re : Défi de programmation JSL : convertir une chaîne de Y et de N en une matrice de 1 et de 0, et inversementTout ce qui marche, ça marche !Voici une alternative.
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));