当列表以逗号开头时,在列表中查找特定实例

时间:2018-07-20 04:05:04

标签: loops coldfusion lucee

我正在上传电子表格,并将电子表格的列标题映射到数据库中的标题。电子邮件列是唯一需要的列。在下面的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

2 个答案:

答案 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时,您的代码应该可以一致地工作。