Reputation: 11
I require a function that exchanges only the characters of the middle of the word (between first and last character). The function should not change anything if the word is composed of less than 4 characters. The function has an argument called exclude
which is a vector of potential punctuation marks at the end of a word.
You can assume that there is only one possible punctuation mark. If there is such a mark, it should not be changed and not counted towards the number of characters the actual word is composed of.
My idea is to
string <-c("well!")
interchange.middle.of.word <- function(string, exclude = c(",",".","!","?")){
result1 <- strsplit(string, split= "")
result2 <- unlist(result1)
result3 <- result2[ - which(result2 %in% exclude)]
result4 <- head(result3,-1)
result5 <- tail(result4,-1)
result6 <- sample(result5,replace = FALSE)
result7 <- c(result3[1],result6)
result8 <- c(result7, result4[length(result4)])
result9 <- c(result8, result2[which(result2 %in% exclude)])
result10 <- paste(result9,collapse="")
return(result10)
}
The code worked for the example 'well!'
, but not for another example like 'hello?'
or words less than 3 letters like 'Tes'
:
'hello?'
my result was 'hlell?'
'Tes'
my result was 'NA'
I would be grateful if anyone can tell me where I went wrong about the code. Many thanks.
Upvotes: 1
Views: 77
Reputation: 35314
Assuming you want to reverse the order of the middle characters:
revmiddle <- function(s,exclude=c(',','.','!','?')) {
if (nchar(s)<4L) return(s);
x <- strsplit(s,'')[[1L]];
if (x[length(x)]%in%exclude) {
punc <- x[length(x)];
x <- x[-length(x)];
} else {
punc <- NULL;
}; ## end if
paste(collapse='',c(x[1L],x[seq(length(x)-1L,2L)],x[length(x)],punc));
}; ## end revmiddle()
Demo:
revmiddle('well!');
## [1] "wlel!"
revmiddle('hello?');
## [1] "hlleo?"
revmiddle('Tes');
## [1] "Tes"
To randomize the order of the middle characters:
randmiddle <- function(s,exclude=c(',','.','!','?')) {
if (nchar(s)<4L) return(s);
x <- strsplit(s,'')[[1L]];
if (x[length(x)]%in%exclude) {
punc <- x[length(x)];
x <- x[-length(x)];
} else {
punc <- NULL;
}; ## end if
paste(collapse='',c(x[1L],sample(x[-c(1L,length(x))]),x[length(x)],punc));
}; ## end randmiddle()
Demo (intentionally performing many executions and collecting sorted unique results, which effectively demonstrates all possible outcomes):
sort(unique(replicate(1e3L,randmiddle('well!'))));
## [1] "well!" "wlel!"
sort(unique(replicate(1e3L,randmiddle('hello?'))));
## [1] "hello?" "hlelo?" "hlleo?"
sort(unique(replicate(1e3L,randmiddle('Tes'))));
## [1] "Tes"
Upvotes: 2