I'm uploading a spreadsheet and mapping the spreadsheet column headings to those in my database. The email column is the only one that is required. In StringB below, the ,,, simply indicates that a column was skipped/ignored.
The meat of my question is this:
I have a string of text (StringA) comes from a spreadsheet that I need to find in another string of text (StringB) which matches my database (this is not the real values, just made it simple to illustrate my problem so hopefully this is clear).
StringA: YR,MNTH,ANNIVERSARIES,FIRSTNAME,LASTNAME,EMAIL,NOTES
StringB: ,YEAR,,MONTH,LastName,Email,Comments <-- this list is dynamic
MNTH and MONTH are intentionally different;
excelColumnList = 'YR,MNTH,ANNIV,FIRST NAME,LAST NAME,EMAIL,NOTES';
mappedColumnList= ',YEAR,,MONTH,,First Name,Last Name,Email,COMMENTS';
mappedColumn= 'Last Name';
local.index = ListFindNoCase(mappedColumnList, mappedColumn,',', true);
local.returnValue = "";
if ( local.index > 0 )
local.returnValue = ListGetAt(excelColumnList, local.index);
writedump(local.returnValue); // dumps "EMAIL" which is wrong
The problem I'm having is the index returned when StringB starts with a , returns the wrong index value which affects the mapping later. If StringB starts with a word, the process works perfectly. Is there a better way to to get the index when StringB starts with a ,?
I also tried using listtoarray and then arraytolist to clean it up but the index is still off and I cannot reliably just add +1 to the index to identify the correct item in the list.
On the other hand, I was considering this mappedColumnList = right(mappedColumnList,len(mappedColumnList)-1) to remove the leading , which still throws my index values off BUT I could account for that by adding 1 to the index and this appears to be reliably at first glance. Just concerned this is a sort of hack.
Any advice?
https://cfdocs.org/listfindnocase
Here is a cfgist: https://trycf.com/gist/4b087b40ae4cb4499c2b0ddf0727541b/lucee5?theme=monokai
UPDATED
I accepted the answer using EDIT #1. I also added a comment here: Finding specific instance in a list when the list starts with a comma
Identify and strip the "," off the list if it is the first character.
EDIT: Changed to a while loop to identify multiple leading ","s.
Try:
while(left(mappedColumnList,1) == ",") {
mappedColumnList = right( mappedColumnList,(len(mappedColumnList)-1) ) ;
}
https://trycf.com/gist/64287c72d5f54e1da294cc2c10b5ad86/acf2016?theme=monokai
EDIT 2: Or even better, if you don't mind dropping back into Java (and a little Regex), you can skip the loop completely. Super efficient.
mappedColumnList = mappedColumnList.replaceall("^(,*)","") ;
And then drop the while loop completely.
https://trycf.com/gist/346a005cdb72b844a83ca21eacb85035/acf2016?theme=monokai
<cfscript>
excelColumnList = 'YR,MNTH,ANNIV,FIRST NAME,LAST NAME,EMAIL,NOTES';
mappedColumnList= ',,,YEAR,MONTH,,First Name,Last Name,Email,COMMENTS';
mappedColumn= 'Last Name';
mappedColumnList = mappedColumnList.replaceall("^(,*)","") ;
local.index = ListFindNoCase(mappedColumnList, mappedColumn,',', true);
local.returnValue = ListGetAt(excelColumnList,local.index,",",true) ;
writeDump(local.returnValue);
</cfscript>
Explanation of the Regex ^(,*):
^ = Start at the beginning of the string.
() = Capture this group of characters
,* = A literal comma and all consecutive repeats.
So ^(,*) says, start at the beginning of the string and capture all consecutive commas until reaching the next non-matched character. Then the replaceall() just replaces that set of matched characters with an empty string.
EDIT 3: I fixed a typo in my original answer. I was only using one list.
writeOutput(arraytoList(listtoArray(mappedColumnList))) will get rid of your leading commas, but this is because it will drop empty elements before it becomes an array. This throws your indexing off because you have one empty element in your original mappedColumnList string. The later string functions will both read and index that empty element. So, to keep your indexes working like you see to, you'll either need to make sure that your Excel and db columns are always in the same order or you'll have to create some sort of mapping for each of the column names and then perform the ListGetAt() on the string you need to use.
By default many CF list functions ignore empty elements. A flag was added to these function so that you could disable this behavior. If you have string ,,1,2,3 by default listToArray would consider that 3 elements but listToArray(listVar, ",", true) will return 5 with first two as empty strings. ListGetAt has the same "includeEmptyValues" flag so your code should work consistently when that is set to true.
my #buildno = $mech->xpath('/html/body/form/table/tbody/tr[2]/td[3]/table
/tbody/tr[2]/td/table/tbody/tr[1]/td/table/tbody/tr[1]/td', type =>
$mech->xpathResult('STRING_TYPE'));
I have the above code which contains a string. I need to capture the word beginning with CSR contained in the array within a string. There is only one element #buildno[0]. I need to keep the word and remove everything else in the string. I have tried using the m// way however it only returns a boolean telling me that the word exists. I have also tried subtituting s/// however I can only remove the word that I need to keep, I cannot figure out a way to reverse that function.
EDIT
I have managed to split the string up and put it into a new array so each word is a seperate index.
my $buildno = join('', #buildno);
my #build = split(' ',$buildno);
print #build[1];
The word I am looking for in this instance is the second element in the array as it is the second word #build[1]however the word may not always be the second word in the string, it could be the fourth word for example. My purpose is to capture that specific word for later use.
You may match the desired word using m// storing it in a capture group and then replace the whole original string with that matched group:
do {$_ = $1 if /(?:^|\s)(CSR\S*)/} foreach #buildno;
Demo: https://ideone.com/1l7YJb
Javascript beginner.
I apply the split() method to the string, and next apply the splice() array method to the words array, removing two words at array "index 3", "really" and "cool" Since the splice () method returns any deleted words to display these in an alert dialog.
But "index" is unhappy with the code.
the output from script is:
JpowerfulaScript is really cool language
I want the output "javascript is perfect language"
enter image description here
Complete solution here
function wrangleArray() {
var sentence = "JavaScript is really cool language";
document.getElementById('div1').innerHTML = "<p>"+ sentence + "</p>";
var words = sentence.split(" ");
words.splice(2, 2, "powerful");
document.getElementById('div2').innerHTML = '<p>'+ words.join(" ") + '</p>';
}
As far as I can see from your code, you have this line:
var words = sentence.split('');
Your mistake here as I see it is, you are not splitting by spaces (' ') but rather by empty strings.
As can be seen from this fiddle splitting by an empty string (the '' entry in your code), means splitting by every character (since after every character you technically do have an empty string).
For example, I have a string A-456-BC-123;DEF-456;GHI-789. And I need to search for second part:DEF-456 with keyword 456. The potential problem here is that the first part A-456-BC-123 also has the keyword 456. Currently my logic is that, split the string first using ;, split each of it again using -, get the last item of this Array, search keyword 456. Another thing is that I don't want to do a full keyword match like DEF-456, I only want to use 456 as keyword to locate DEF-456, in other words, 456 should be the last segment of the string I want.
Here are my codes:
FirstSplit= split("A-456-BC-123;DEF-456;GHI-789",";")
For each code in FirstSplit
SecondSplit = split(FirstSplit,"-")
'get Array Count
Count = Ubound(SecondSplit)
'get the last item in Array
If SecondSplit(Count-1) = "456" Then
'doing something
End if
Next
Currently, an error will generate at SecondSplit(Count-1), saying that "Subscript out of range: '[number: -1]'"
Could someone tell me how to fix it?
The real problem is here:
SecondSplit = Split(FirstSplit, "-")
You should be splitting your element which you've stored in variable code from your For Each loop. By trying to split an array you should be getting a Type Mismatch error, but perhaps vbscript is forgiving enough to attempt and return a 0 element array back or something. Anyway:
SecondSplit = Split(Code, "-")
Also, to look at the last element just use:
If secondSplit(Ubound(SecondSplit)) = "456" Then
Subtracting 1 from the ubound would get you the second to last element.
You don't need to split it twice - what you're looking for is Right():
FirstSplit = split("A-456-BC-123;DEF-456;GHI-789",";")
For each code in FirstSplit
If Right(code, 3) = "456" Then
' do something
End If
Next
Though this would also match an entry like ABC-1456. If the - symbol is a required delimiter, you'd have to say If Right(code, 4) = "-456".
I am currently building an Book-App (sort of). So there are a lot of Strings, and the User can choose from which line he wants to start reading. So e.g there are 200 Strings in a String Array for Chapter one. And the User wants to start reading at Line 20(because he read the Lines before already). How can I display all the Strings from 20-200?
I have got:
Resources res = getResources();
String[] Book= res.getStringArray(R.array.ChapterOne);
TextView ChapterOne= (TextView) findViewById(R.id.Text);
SuraAlFateha.setText(Book[20]);
But This just diplays the Line 20. But I want it to Display All the Lines following from 20 (20-200).
How can I do this?
Thank you.
When you set the text you need to set all the text at once, like:
String resultString = '';
for ( int i = 20; i < Book.length; i++ )
resultString = resultString + "\n" + Book[i];
SuraAlFateha.setText( resultString.substring( 1 ) );
or something similar.
You should however calculate how much space you need and reserve it before starting the string appending or else your runtime and memory usage might get sky high.
Book[20] will simply give you the 20th element of the array, if you wish to get text for 20 through the end, you'll need to join the range of elements into a string.
You can use text and array utils to make this easy.
String joinedLines = TextUtils.join("\n", java.utils.Arrays.copyOfRange(Book, 20, Book.length));
SuraAlFateha.setText(joinedLines);