我正在上传电子表格,并将电子表格的列标题映射到数据库中的标题。电子邮件列是唯一需要的列。在下面的StringB中,,,,
仅表示已跳过/忽略了列。
我要问的是这个问题:
我有一个文本字符串(StringA)来自电子表格,我需要在另一个与我的数据库匹配的文本字符串(StringB)中找到(这不是真实值,只是为了简单说明我的问题,所以希望这很清楚)。
StringA:YR,MNTH,ANNIVERSARIES,FIRSTNAME,LASTNAME,EMAIL,NOTES
StringB:,YEAR,,MONTH,LastName,Email,Comments
<-此列表是动态的
MNTH 和 MONTH 故意不同;
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
我遇到的问题是StringB以,
开头时返回的索引返回了错误的索引值,这会在以后影响映射。如果StringB以一个单词开头,则该过程可以正常运行。当StringB以,
开头时,是否有更好的方法来获取索引?
我还尝试使用listtoarray
,然后使用arraytolist
进行清理,但是索引仍然关闭,我不能可靠地将+1添加到索引中以标识列表中的正确项。 / p>
另一方面,我正在考虑使用此mappedColumnList = right(mappedColumnList,len(mappedColumnList)-1)
来删除前导,
,但仍将我的索引值丢弃,但我可以通过在索引上加1来解决这个问题,这似乎是乍一看可靠。只是担心这是一种黑客行为。
有什么建议吗?
https://cfdocs.org/listfindnocase
以下是一名信仰者:https://trycf.com/gist/4b087b40ae4cb4499c2b0ddf0727541b/lucee5?theme=monokai
已更新 我使用EDIT#1接受了答案。我还在这里添加了评论:Finding specific instance in a list when the list starts with a comma
答案 0 :(得分:2)
如果“,”是第一个字符,则将其识别并从列表中删除。
编辑:更改为while
循环以标识多个前导“,”。
尝试:
while(left(mappedColumnList,1) == ",") {
mappedColumnList = right( mappedColumnList,(len(mappedColumnList)-1) ) ;
}
https://trycf.com/gist/64287c72d5f54e1da294cc2c10b5ad86/acf2016?theme=monokai
编辑2:甚至更好的是,如果您不介意重新使用Java(以及少许Regex),则可以完全跳过循环。超高效。
mappedColumnList = mappedColumnList.replaceall("^(,*)","") ;
然后完全丢弃while
循环。
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>
正则表达式^(,*)
的解释:
^
=从字符串的开头开始。 ()
=捕获这组字符,*
=文字逗号和所有连续的重复。因此^(,*)
说,从字符串的开头开始并捕获所有连续的逗号,直到到达下一个不匹配的字符为止。然后replaceall()
会将匹配的字符集替换为空字符串。
编辑3:我修复了原始答案中的错字。我只使用一个列表。
writeOutput(arraytoList(listtoArray(mappedColumnList)))
会删除您的前导逗号,但这是因为它将在成为数组之前删除空元素。因为您的原始mappedColumnList
字符串中只有一个空元素,所以这使索引编制工作陷入困境。后面的字符串函数将读取并索引该空元素。因此,要使索引如您所愿地工作,您要么需要确保Excel和db列始终保持相同的顺序,要么必须为每个列名创建某种映射,并且然后在您需要使用的字符串上执行ListGetAt()
。
答案 1 :(得分:0)
默认情况下,许多CF列表函数会忽略空元素。一个标志已添加到这些功能,以便您可以禁用此行为。如果默认情况下有字符串SELECT @num1, (CASE WHEN @num1 is not null
THEN RIGHT(CONCAT('00', CONVERT(VARCHAR,@num1)),2)
ELSE space(1)
END) as 'output'
,listToArray会认为这3个元素,但是,,1,2,3
将返回5,其中前两个为空字符串。 ListGetAt具有相同的“ includeEmptyValues”标志,因此当将其设置为true时,您的代码应该可以一致地工作。