PDA

View Full Version : Challenge - Extending the String Class


madgett
04-04-2005, 07:32 PM
Ok, for those of you who complained about the hundredth time someone challenged for the rotating cube...

Try this:
Extend the String Class so that...

A) The class has all of the methods of the String Class
B) Adds only 1 other method which allows for the String to be split by muliple delimiters. Must return an array. (Much like the original split() but better :) )
C) Class must be 25 lines of code or less. Only {} Don't count.
D) Must be your own work...obviously.

E)...It must have a constructor. -added within 5mins of thread post-

The class with the most capability and fewest lines wins. Abviously following the list above.

I will post mine after we get a few going...I've already done it.

senocular
04-04-2005, 08:06 PM
what do you mean by "better"?

madgett
04-04-2005, 08:10 PM
The split() command current only accepts 1 delimiter set. "," or ",#" etc...but that's only 1, I am saying come up with a Class that extends String that allows for multiple delimiter sets at the same time instead of one. Know what I mean? So you would be able to use "," and ",#" if you so choose.

senocular
04-04-2005, 08:57 PM
you mean something like this?
Array.prototype.toString = function(){
return "[" + this.join(",") + "]";
}
String.prototype.split2 = function(d,a){
if ((d=arguments.shift()) != undefined && (a=this.split(d))) for(var i in a) a[i]=this.split2.apply(a[i],arguments);
return d != undefined ? a : this;
}
var str = "oneA,twoA|oneB|oneC,twoC,threeC|oneD,twoD";
trace(str.split2("|",",")); // [[oneA,twoA],[oneB],[oneC,twoC,threeC],[oneD,twoD]]

madgett
04-04-2005, 09:10 PM
Looks very interesting senocular, now all you have to do is make it a ActionScript Class that extends the String Class and returns an array. Make sure you have A-E.

senocular
04-04-2005, 09:44 PM
eh, its just a syntax thing

madgett
04-04-2005, 09:49 PM
If you do:
var my_str:String = "P,A,T,S,Y";
var my_array:Array = my_str.split(",");
for (var i = 0; i<my_array.length; i++) {
trace(my_array[i]);
}
You get:
output:
P
A
T
S
Y

I'm getting nested arrays with your prototypes. Use a class :). Ideally you should get the same output even using the multiple delimiter technique which the challenge is proposing.

Xeef
04-04-2005, 10:35 PM
here one line :D
hope you not think i will make a class for ONE line ? :p
String.prototype.split2 = function() {
return arguments[0] ? this.split2.apply(this.split(arguments.shift()).jo in("º"), arguments) : this.split("º");
};
a = "Hallo-by?Xeef:just:for?testing-blabla;more$testing)to>By/sure";
trace(a.split2("-", "?", ":", ">", "/", "$", ")", ";", "this to test if not in", "F"));


one bad thing "º" sucks

madgett
04-04-2005, 11:51 PM
Well, anyone can prototype in few lines...but that's not the challenge, I want to see some classes. To get the fewest lines in a class is more challenging. You guys came up with some great stuff, but use a class. In the String.split() function there's a "limit" parameter, those prototypes don't include that.

Also, Xeef your prototype fails if you use º in the string. I'm sure a class couldn't be that much more difficult...I mean c'mon. My entire class with the contructor is 17 lines. Shoot for that.

Xeef
04-05-2005, 12:11 AM
to do a class is no problem but for what ?
it's like make a chalenge to write a class which trace a variable to screen
in such a case i write
trace(var)
and not make a class
it's a bit like taking cement stones and a roof for go camping
where by what woud by the advantage of a class in oposite to the prototypes you see above ?

Also, Xeef your prototype fails if you use º in the string
as you can see the last line of my message i am aware of this my objective was to make it as short as possible

madgett
04-05-2005, 12:36 AM
to do a class is no problem but for what ?
it's like make a chalenge to write a class which trace a variable to screen
in such a case i write
trace(var)
and not make a class
it's a bit like taking cement stones and a roof for go camping
where by what woud by the advantage of a class in oposite to the prototypes you see above ?
I guess there's no purpose for challenges then...if all anybody's going to do it work around them. Is the challenge to work around the challenge? I'm at least glad you met your own objectives :), which is what I guess matters in the long run.

For everyone else willing to participate in the challenge as stated then please do.

Xeef
04-05-2005, 01:13 AM
so "º" problem fixed
limit build in
it's late so not realy test it but it's seams to work still ALL on 1 line ;)

String.prototype.split2 = function() {
return (arguments[0] && arguments[0]+1<>Number(arguments[0])+1) ? this.split2.apply(this.split(Delimit=arguments.shi ft()).join(arguments[arguments.length-1]), arguments) : (arguments[0]+1<>Number(arguments[0])+1) ? this.split(Delimit) : this.split(arguments[arguments.length-1]).slice(0, arguments[arguments.length-1]);
};
a = "Hallo-by?Xeef:just:for?testing-blabla;more$testing)to>By/sure";
trace(a.split2("-", "?", ":", ">", "/", "$", ")", ";", "this to test if not in", "F", 3));

senocular
04-05-2005, 10:06 AM
it doesnt really matter if you use a class or a prototype, its all the same in the end. A class just means the extra default class baggage of class name extends string. The function is still there and in the same format and producing the same results

My split2 does exactly what I intended it to do. It splits a string with multiple delimiters returning a multidimensional array of the results. You never said anything about what the return value should be, just that it needs to be a split that accepts multiple delimiters and thats what I came up with. The array prototype just helps you see that in the trace.

madgett
04-05-2005, 04:42 PM
It may have done what you wanted, but it's definitely not the best way. And how can a user keep track of dynamically created arrays constantly embedding themselves? Not to be harsh, but if your going to prototype, at least make it better than that...

it doesnt really matter if you use a class or a prototype, its all the same in the end. A class just means the extra default class baggage of class name extends string. The function is still there and in the same format and producing the same results
Is that so? Prototyping is very limited to a class. By writing a class, which probably took no more time than for you to come up with your prototype I can now call it from any timeline without have to copy and past the method every time I wanted to use it, which is what you would be forced to do. When you prototype your suedo adding methods to an existing class. What's the point of classes then? Prototyping is significantly limiting to the power of classes and extending and reusing code.

Xeef
04-05-2005, 05:03 PM
B) Adds only 1 other method which allows for the String to be split by muliple delimiters

this already discualyfi it for a class !

but we have show you ours so lets see yours :p (even if we don-t make classes)

senocular
04-05-2005, 05:10 PM
for the purposes of a challenge it shouldnt matter. If anyone wants to make their own class out of the string method, they can do so with little trouble. What matters is what it does. And when its a challenge of small code count, it matters how many lines it takes. I made mine in 4 lines (counting the closing }) and Xeef one in less. Both seemed to satisfy the conditions of the challenge well enough so I wouldnt complain :D

madgett
04-05-2005, 05:11 PM
A class is a class, whether it adds one other method or not. Especially when you compile as a class.
dynamic class StringDelim extends String {
private var ºººººº;
public function StringDelim(ººººººº) {
super(ººººººº);
ºººººº = ººººººº;
}
public function delimsplit(ºººººººººº, ººººººººººº):Array {
var ºººº = ºººººº.substring(0, ººººººººººº);
var ºººººººº = [];
for (var ºº = 0; ºº<ºººººººººº.length; ++ºº) {
ºººººººº = ºººººººººº[ºº].split("");
(ºº == 0) ? ºººººº=ºººººººººº[ºº] : null;
for (var ººº = 0; ººº<ºººººººº.length; ++ººº) {
for (var º = 0; º<ºººº.split(ºººººººº[ººº]).length; ++º) {
var ººººººººº = ºººº.indexOf(ºººººººº[ººº], 0);
if (ºººº.indexOf(ºººººººº[ººº], 0) != -1) {
ºººº = ºººº.slice(0, ººººººººº).concat(ºººººº, ºººº.slice(ººººººººº+1, ºººº.length));
}
}
}
}
return ºººº.split(ºººººº);
}
}
Timeline:var str:StringDelim = new StringDelim("Hallo-by?Xeef:just:for?testingº-blabla;more$testing)to>By/sure");
var arr:Array = str.delimsplit(["/", "?", ":", ">", "-", "$", ")", ";", ",", "F"], str.length); // delimsplit(delimiters:Array, limit:Number)
trace(arr);

Classes are way better than prototypes.

Xeef
04-05-2005, 06:13 PM
one big disadwantage !

str+="a bit more text"
or
str="New text"

Type mismatch in assignment statement: found String where StringDelim is required.
woud realy like to see how you fix this :p (not think on it to much but i think it's unfixable unless whit extra methodes to add to the string which woud by a nightmare by writing code)

and one more bug and i think to fix this you will need to rewrite you hole logic

var str:StringDelim = new StringDelim("Hallo-Test123Xeef");
//str+="a by more text"
var arr:Array = str.delimsplit(["123", "-","ab"], str.length);
trace(arr);
String.prototype.split2 = function() {
return (arguments[0] && arguments[0]+1<>Number(arguments[0])+1) ? this.split2.apply(this.split(Delimit=arguments.shi ft()).join(arguments[arguments.length-1]), arguments) : (arguments[0]+1<>Number(arguments[0])+1) ? this.split(Delimit) : this.split(arguments[arguments.length-1]).slice(0, arguments[arguments.length-1]);
};
var str2 = ("Hallo-Test123Xeef");
str2 += " a by more text";
trace(str2.split2("123", "-","ab"));

madgett
04-05-2005, 07:51 PM
one big disadwantage !

str+="a bit more text"
or
str="New text"

Type mismatch in assignment statement: found String where StringDelim is required.
I wrote a class extending the string class, you can't expect an extending class to automatically respond to actions based completely on a different class. The += operation is not a method of the String class. Therefore you use concat:
str = new StringDelim(str.concat("ok"));You still have to follow the rules as if it were any other class. Since the String class returns of type "String" using concat then you have to Cast it to the StringDelim Class.
str = "text";By default "text" is of type String so you have to cast that also when assigning (again just like you would any other custom class).
str = new StringDelim("text");
and one more bug and i think to fix this you will need to rewrite you hole logicThanks for point out the bug, I had to add a couple more º. However, no lines added :)
StringDelim.as:dynamic class StringDelim extends String {
private var ºººººº;
public function StringDelim(ººººººº) {
super(ººººººº);
ºººººº = ººººººº;
}
public function delimsplit(ºººººººººº, ººººººººººº):Array {
var ºººº = ºººººº.substring(0, ººººººººººº);
var ºººººººº = [];
for (var ºº = 0; ºº<ºººººººººº.length; ++ºº) {
ºººººººº = ºººººººººº[ºº].split(",");
(ºº == 0) ? ºººººº=ºººººººººº[ºº] : null;
for (var ººº = 0; ººº<ºººººººº.length; ++ººº) {
for (var º = 0; º<ºººº.split(ºººººººº[ººº]).length; ++º) {
var ººººººººº = ºººº.indexOf(ºººººººº[ººº], 0);
if (ºººº.indexOf(ºººººººº[ººº], 0) != -1) {
ºººº = ºººº.slice(0, ººººººººº).concat(ºººººº, ºººº.slice(ººººººººº+ºººººººººº[ºº].length, ºººº.length));
}
}
}
}
return ºººº.split(ºººººº);
}
}
On the root timeline:
var str:StringDelim = new StringDelim("Hallo-Test123Xeef");
str = new StringDelim(str.concat(" a by more text"));
var arr:Array = str.delimsplit(["123", "-", "ab"], str.length);
trace(arr);
String.prototype.split2 = function() {
return (arguments[0] && arguments[0]+1<>Number(arguments[0])+1) ? this.split2.apply(this.split(Delimit=arguments.shi ft()).join(arguments[arguments.length-1]), arguments) : (arguments[0]+1<>Number(arguments[0])+1) ? this.split(Delimit) : this.split(arguments[arguments.length-1]).slice(0, arguments[arguments.length-1]);
};
var str2 = ("Hallo-Test123Xeef");
str2 += " a by more text";
trace(str2.split2("123", "-", "ab"));

Xeef
04-05-2005, 08:54 PM
no still not working :p

TEST_STR = "Hallo--------this-is a-123-ab-TEST)";
var str:StringDelim = new StringDelim(TEST_STR);
str = new StringDelim(str.concat(" a by more text"));
var arr:Array = str.delimsplit(["123", "-", "ab"], str.length);
trace("By madgett");
trace(arr);
String.prototype.split2 = function() {
return (arguments[0] && arguments[0]+1<>Number(arguments[0])+1) ? this.split2.apply(this.split(Delimit=arguments.shi ft()).join(arguments[arguments.length-1]), arguments) : (arguments[0]+1<>Number(arguments[0])+1) ? this.split(Delimit) : this.split(arguments[arguments.length-1]).slice(0, arguments[arguments.length-1]);
};
var str2 = (TEST_STR);
str2 += " a by more text";
trace("By Xeef");
trace(str2.split2("123", "-", "ab"));
//this to see the original out put (of course just 1 delimiter)
trace("By MM split by '-'");
trace(TEST_STR.split("-")+" a by more text");
//
trace("----------------------");
TEST_STR = "a-b-c-d-e-f";
trace("By madgett");
var str:StringDelim = new StringDelim(TEST_STR);
trace(str.delimsplit(["-"], 5));
trace("By Xeef");
var str2 = (TEST_STR);
trace(str2.split2("-", 5));
trace("By MM");
trace(TEST_STR.split("-", 5));



dynamic class StringDelim extends String {
private var PRV_STR;
public function StringDelim(ORG_STR) {
super(ORG_STR);
PRV_STR = ORG_STR;
}
public function delimsplit(delimitARR, Limit):Array {
var ERROR = PRV_STR.substring(0, Limit);
var B = [];
for (var b = 0; b<delimitARR.length; ++b) {
B = delimitARR[b].split(",");
(b == 0) ? PRV_STR=delimitARR[b] : null;
for (var a = 0; a<B.length; ++a) {
for (var c = 0; c<ERROR.split(B[a]).length; ++c) {
var A = ERROR.indexOf(B[a], 0);
if (ERROR.indexOf(B[a], 0) != -1) {
ERROR = ERROR.slice(0, A).concat(PRV_STR, ERROR.slice(A+delimitARR[b].length, ERROR.length));
}
}
}
}
return ERROR.split(PRV_STR);
}
}


The += operation is not a method of the String class
that can by but is use this day and night and it's a pain in the ass whit you class

madgett
04-05-2005, 09:26 PM
It is working, the only difference is the definition of what "limit" is. In my class the limit is taking into account only the first 5 characters of the original string, rather than the first 5 objects of the array. If you want it to do the first five objects of the array instead of the string change:
return ERROR.split(PRV_STR, limit);
Another bug :p
I have too much information in the for loop:
for (var c = 0; c<ERROR.length; ++c) {
:) no more bugs.

The whole point of using this method in a class would be after you've already done the string manuplations with the normal string class. Then you would cast it to StringDelim and use the delimsplit() method. You don't have to manipulate strings inside the contents of the class. You do the manipulations first then cast it and apply the method.
dynamic class StringDelim extends String {
private var str:String;
public function StringDelim(tstr:String) {
super(tstr);
str = tstr;
}
public function delimsplit(tarr:Array, limit:Number):Array {
var finalStr:String = str;
var strArr:Array = new Array();
for (var c = 0; c<tarr.length; ++c) {
strArr = tarr[c].split(",");
(c == 0) ? str=tarr[c] : null;
for (var i = 0; i<strArr.length; ++i) {
for (var v = 0; v<finalStr.length; ++v) {
var indA:Number = finalStr.indexOf(strArr[i], 0);
if (finalStr.indexOf(strArr[i], 0) != -1) {
finalStr = finalStr.slice(0, indA).concat(str, finalStr.slice(indA+tarr[c].length, finalStr.length));
}
}
}
}
return finalStr.split(str, limit);
}
}

TEST_STR = "Hallo--------this-is a-123-ab-TEST)";
var str:StringDelim = new StringDelim(TEST_STR);
str = new StringDelim(str.concat(" a by more text"));
var arr:Array = str.delimsplit(["123", "-", "ab"], str.length);
trace("By madgett");
trace(arr);
String.prototype.split2 = function() {
return (arguments[0] && arguments[0]+1<>Number(arguments[0])+1) ? this.split2.apply(this.split(Delimit=arguments.shi ft()).join(arguments[arguments.length-1]), arguments) : (arguments[0]+1<>Number(arguments[0])+1) ? this.split(Delimit) : this.split(arguments[arguments.length-1]).slice(0, arguments[arguments.length-1]);
};
var str2 = (TEST_STR);
str2 += " a by more text";
trace("By Xeef");
trace(str2.split2("123", "-", "ab"));
//this to see the original out put (of course just 1 delimiter)
trace("By MM split by '-'");
trace(TEST_STR.split("-")+" a by more text");
//
trace("----------------------");
TEST_STR = "a-b-c-d-e-f";
trace("By madgett");
var str:StringDelim = new StringDelim(TEST_STR);
trace(str.delimsplit(["-"], 5));
trace("By Xeef");
var str2 = (TEST_STR);
trace(str2.split2("-", 5));
trace("By MM");
trace(TEST_STR.split("-", 5));

Xeef
04-05-2005, 10:14 PM
Grrrrrr find something which ****s my one :(

but yours also have one more bug :p

var arr:Array = str.delimsplit(["123", "-a", "-", ",", "ab"], str.length);

madgett
04-06-2005, 05:00 AM
Ok, I had to play by the rules of escaping strings...yes sneaky isn't it :rolleyes:
dynamic class StringDelim extends String {
private var str:String;
public function StringDelim(tstr:String) {
super(tstr);
str = tstr;
}
public function delimsplit(tarr:Array, limit:Number, diff:String):Array {
var finalStr:String = str;
(str.indexOf("'", 0) == -1 && str.indexOf("\"", 0) != -1) ? str="\'\\" : str='\"\\';
for (var c = 0; c<tarr.length; ++c) {
for (var i = 0; i<tarr[c].length; ++i) {
for (var v = 0; v<finalStr.length; ++v) {
var indA:Number = finalStr.indexOf(tarr[c], 0);
if (finalStr.indexOf(tarr[c], 0) != -1) {
finalStr = finalStr.slice(0, indA).concat(str, finalStr.slice(indA+tarr[c].length, finalStr.length));
}
}
}
}
return finalStr.split(str, limit);
}
}

TEST_STR = "Hallo--------1th\\1\\\\\'\\\"is-is a-123-,-ab-TEST)";
var str:StringDelim = new StringDelim(TEST_STR);
str = new StringDelim(str.concat(" a by more text"));
var arr:Array = str.delimsplit(["\\'", "\\1", "-", ",", "ab"], str.length);
trace("By madgett");
trace(arr);
String.prototype.split2 = function() {
return (arguments[0] && arguments[0]+1<>Number(arguments[0])+1) ? this.split2.apply(this.split(Delimit=arguments.shi ft()).join(arguments[arguments.length-1]), arguments) : (arguments[0]+1<>Number(arguments[0])+1) ? this.split(Delimit) : this.split(arguments[arguments.length-1]).slice(0, arguments[arguments.length-1]);
};
var str2 = (TEST_STR);
str2 += " a by more text";
trace("By Xeef");
trace(str2.split2("\\'", "\\1", "-", ",", "ab"));
//this to see the original out put (of course just 1 delimiter)
trace("By MM split by '-'");
trace(TEST_STR.split("-")+" a by more text");
//
trace("----------------------");
TEST_STR = "a-b-c-d-e-f";
trace("By madgett");
var str:StringDelim = new StringDelim(TEST_STR);
trace(str.delimsplit(["-"], 5));
trace("By Xeef");
var str2 = (TEST_STR);
trace(str2.split2("-", 5));
trace("By MM");
trace(TEST_STR.split("-", 5));

madgett
04-06-2005, 05:05 AM
LOL, I can't even post my answer cause the Forum is escaping the strings I had in there :p ...bummer. Well here is the attached class.

Xeef
04-06-2005, 10:42 AM
i still can **** it :p

ok it's very unlikely that you have to diel whit such a string but ...

TEST_STR = 'abc"\abc';
var str:StringDelim = new StringDelim(TEST_STR);
str = new StringDelim(str.concat("abc'\abc"));
trace(str)
var arr:Array = str.delimsplit([","], str.length);
trace("By madgett");
trace(arr);

madgett
04-06-2005, 12:22 PM
....yeah I need 1 more slash than all the slashes in the string. :p

madgett
04-06-2005, 01:07 PM
Ok, it is impossible to mess this. All I did was add 1 extra character, which can be anything, to the original string and use that as the delimiter. It is impossible to "resimulate" the delimiter because it always has 1 more character than the original string :).
dynamic class StringDelim extends String {
private var str:String;
public function StringDelim(tstr:String) {
super(tstr);
str = tstr;
}
public function delimsplit(tarr:Array, limit:Number, diff:String):Array {
var finalStr:String = str;
str += "a"; // <- can put anything in here
for (var c = 0; c<tarr.length; ++c) {
for (var i = 0; i<tarr[c].length; ++i) {
for (var v = 0; v<finalStr.length; ++v) {
var indA:Number = finalStr.indexOf(tarr[c], 0);
if (finalStr.indexOf(tarr[c], 0) != -1) {
finalStr = finalStr.slice(0, indA).concat(str, finalStr.slice(indA+tarr[c].length, finalStr.length));
}
}
}
}
return finalStr.split(str, limit);
}
}

madgett
04-06-2005, 01:09 PM
Sad, I did a simple test and find a bug?! :p...wow can this be that difficult?????

madgett
04-06-2005, 02:19 PM
This is the only way: Accept another parameter, but it must be different than any of the other delimiters used to parse the text. I thought of this earlier, but thought there was a workaround...guess not.
dynamic class StringDelim extends String {
private var str:String;
public function StringDelim(tstr:String) {
super(tstr);
str = tstr;
}
public function delimsplit(tarr:Array, diff:String, limit:Number):Array {
var finalStr = str;
str = diff;
for (var c = 0; c<tarr.length; ++c) {
for (var i = 0; i<tarr[c].length; ++i) {
for (var v = 0; v<finalStr.length; ++v) {
var indA:Number = finalStr.indexOf(tarr[c], 0);
if (finalStr.indexOf(tarr[c], 0) != -1) {
finalStr = finalStr.slice(0, indA).concat(str, finalStr.slice(indA+tarr[c].length, finalStr.length));
arr.push(str);
}
}
}
}
return finalStr.split(str, limit);
}
}

TEST_STR = 'abc"\abc';
var str:StringDelim = new StringDelim(TEST_STR);
str = new StringDelim(str.concat("abc'\abc"));
trace(str)
var arr:Array = str.delimsplit([","], "/", str.length);
// or
// var arr:Array = str.delimsplit([","], "/");
trace("By madgett");
trace(arr);

Xeef
04-06-2005, 02:25 PM
nah

not working at all

a script in this movie causing flash player to run slow ....

Xeef
04-06-2005, 02:28 PM
hup was using the old FLA

need to chek one more time

madgett
04-06-2005, 02:58 PM
What script are you using? The second parameter in delimsplit() has to be different than any of the first ones. And it can't be in the original string :( Which was the logic you were using with the Degree symbol.

Xeef
04-06-2005, 06:43 PM
:D you was posting betwean i was testing !
so forget the "script runing slow"

madgett
04-06-2005, 07:28 PM
Yeah I noticed that, I forgot your internet is too slow :rolleyes: :p

Stu
04-19-2005, 09:44 PM
Am i too late?

14 lines discounting {}

Probably could be more efficient though, as it processes everything and then applies the limit.

Apologies for the gratuitious j=j in the for loop, but it saved a line on declaring a var for a while loop.

class usage:

Strung.splat("delim":String, ["delim2":String, "delim3":String, [limit:Number]])

As many delim parameters as you like, followed by an optional limit parameter.
class Strung extends String {
public function Strung(the_string:String) {
super(the_string);
}
public function splat():Array {
var return_array = new Array(this);
var limit:Number = (typeof(arguments[arguments.length-1])=="number")?arguments[arguments.length-1]:Number.POSITIVE_INFINITY;
for (var i=0; i<arguments.length; i++) {
for (var j=0; j<return_array.length; j=j) {
var temp_array = return_array.splice(j, 1)[0].split(arguments[i]);
for (var k=0; k<temp_array.length; k++) {
return_array.splice(j+k, 0, temp_array[k]);
}
j += temp_array.length;
}
}
return_array.splice(limit, return_array.length-limit);
return (return_array);
}
}

And to test on the timeline..var str:Strung = new Strung("It's#as simple|as something*that~nobody knows~that her#eyes are as*big as her bubbly toes");
trace("original Strung = " + str);
var str_splat:Array = str.splat(" ", "|", "~", "#", "*", 7);
trace ("Strung.splat = " + str_splat);
but I bet someone breaks it in 5 minutes...

madgett
04-19-2005, 10:17 PM
Yeah, it messes up when the delimiter string is longer than 2.

var str:Strung = new Strung("It's#as simple|as something*that~nobody knows~that her#eyes are as*big as her bubbly toes");
trace("original Strung = " + str);
var str_splat:Array = str.splat(" ", "|", "~that", "#", "*", 7);
trace ("Strung.splat = " + str_splat);

madgett
04-19-2005, 10:39 PM
By the way Stu thanks for participating! :)

Forget that last post, I messed up not you.

However I found a bug :p. You use length of the string as your last delimiter. So if you put the the number in the string that represents the length of the string it cuts it out when it shouldn't.

In this case 91 is the length of the string, however, it's not in the delimiter so it shouldn't cut "something" in half, but it does.
var str:Strung = new Strung("It's#as simple|as some91thing*that~nobody knows~that her#eyes are as*big as her bubbly toes");
trace("original Strung = " + str);
var str_splat:Array = str.splat(" ", "|", "~that", "#", "*", str.length);
trace ("Strung.splat = " + str_splat);

Stu
04-19-2005, 11:26 PM
Well spotted!

It checks for the last parameter being a Number for the limit, but forgot to discount it if not a String when applying the delimiters.

Crept up to 15 lines...class Strung extends String {
public function Strung(the_string:String) {
super(the_string);
}
public function splat():Array {
var return_array = new Array(this);
var limit:Number = (typeof(arguments[arguments.length-1])=="number")?arguments[arguments.length-1]:Number.POSITIVE_INFINITY;
for (var i=0; i<arguments.length; i++) {
if (typeof(arguments[i]) == "string") {
for (var j=0; j<return_array.length; j=j) {
var temp_array = return_array.splice(j, 1)[0].split(arguments[i]);
for (var k=0; k<temp_array.length; k++) {
return_array.splice(j+k, 0, temp_array[k]);
}
j += temp_array.length;
}
}
}
return_array.splice(limit, return_array.length-limit)
return (return_array);
}
}

madgett
04-20-2005, 12:19 AM
Excellent!

Looks rock solid, plus you can lose another line with the return statement by going like this:
return return_array.splice(limit, return_array.length-limit);
Good job! :)

With mine, I used split at the end rather than doing it the way you did, by splitting it immediately and then splicing as the drop back, nicely done.

Stu
04-20-2005, 06:48 AM
Thanks !

Unfortunately can't lose that line at the end.

Splice actually returns what was removed from the array, not the resulting array - something I took advantage of earlier in the code, so I cant have it both ways... :)

madgett
04-20-2005, 06:50 AM
Ah yes, I see now why you had to do it. Great job!

edw
03-20-2007, 05:10 PM
It's not an answer to the original challenge but I had scanned the web trying to find any example of overriding the String class to extend its functionality and couldn't find one. I figured it out so I figured I'd post so others may be able to find it.

class stringEx extends String
{
// We need to call the constructor for the String class.
function stringEx(value:String)
{
super(value);
}

function Replace(match:String, replacement:String): stringEx
{
// You can access the string value from the super like so:
var sourceString:String = String(this);

// Perform replace functionality here.
//...
}
}

Stu
03-21-2007, 07:55 AM
For a quick'n'dirty, case sensitive replace all, how about...class StringEx extends String {

function StringEx(value:String) {
super(value);
}

function replace(match:String, replacement:String):StringEx {
// split the string to an array, using the match param as the delimiter
// and join the resulting array to a string using replacement as the delim
return new StringEx(this.split(match).join(replacement));
}
}
Example:var test_str:StringEx = new StringEx("hello, this is my test string. this is to test the StringEx.replace method");

trace(test_str);

trace(test_str.replace("this is", "that was"));
// outputs: hello, that was my test string. that was to test the StringEx.replace method

test_str = new StringEx("Hello, this is my test string. This is to test the StringEx.replace method");

// case sensitive - doesn't replace the "This is"..
trace(test_str.replace("this is", "that was"));
// outputs: Hello, that was my test string. This is to test the StringEx.replace method

Cheers,
Stu

Assertnfailure
03-23-2007, 02:25 AM
The problem with these is that there's really no reason to make the class inherit from String. All you're doing is performing a single isolated operation to an otherwise generic datatype.

A better alternative would be something more like:

class StringEx {

static public function replace(oldstr:String, match:String, replacement:String):String {
return oldstr.split(match).join(replacement);
}
}

monsieurfil
04-09-2007, 10:55 AM
I'm late, but what about:
class StringEx
{
static function split(src /*, all, your, separators*/)
{
var n:Number = arguments.length-1;
var last:String = arguments[n];
for(var i=1; i<n; i++) src = src.split(arguments[i]).join(last);
return src.split(last);
}
}