Как удалить повторяющиеся значения из массива Coldfusion - PullRequest
0 голосов
/ 22 сентября 2018

Как удалить повторяющиеся значения из списка массивов в Coldfusion.

В настоящее время у меня есть следующее, которое отображает причину, по которой пользователь попадает в больницу:

<cfset ReasonforVisit = "#HospitalVisits2.Reason_For_Visit#">
    <cfset counter1 = 1>
    <cfif len(ReasonforVisit)>
      <cfloop query="HospitalVisits2">  
        <cfoutput>
            &nbsp;#HospitalVisits2.Reason_For_Visit#<cfif counter1 LT HospitalVisits2.recordcount>,</cfif>  <cfset counter1++>
        </cfoutput>
      </cfloop></cfif>

Проблема сэтот подход не учитывает дубликаты в столбцах.

Я сделал следующее, чтобы сохранить результаты столбцов в массиве и проверить, если дублирует, но не работает.Что я делаю не так?

<cfset ReasonforVisit = "#HospitalVisits2.Reason_For_Visit#">
<cfset ReasonList = ArrayNew(ReasonforVisit)>

    <cfloop index="i" from="1" to="#arraylen(ReasonList)#">
            <cfset currReasonList = ReasonList[i]>
            <cfset nextReasonList = ReasonList[i+1]>
            <cfif currReasonList NEQ nextReasonList>
                <cfset newReasonList = ArrayNew(newcurrReasonList)>
            <cfelse>
        </cfif>
    </cfloop>
<cfoutput>#newReasonList#</cfoutput>

Ответы [ 2 ]

0 голосов
/ 23 сентября 2018

Возможно, я неверно истолковываю то, что вы действительно ищете, и если это так, я изменю свой ответ.Исходя из того, что вы нам показали, вы не хотите удалять значение из массива.Вы хотите вывести список с разделителями-запятыми Reason_For_Visit с удаленными дубликатами, правильно?

С объектами запросов ColdFusion довольно легко работать, и они были одной из самых мощных функций CF с тех порочень рано в жизни языка.

Объекты запросов ColdFusion уже имеют множество свойств массивов и структур, и многие из тех же функций и поведения этих сложных типов данных могут быть применены обратно к объектам cfquery.

Что выПо сути, запрос может быть выполнен в одной строке (содержащей несколько функций).

newReasonList = listChangeDelims( 
    listRemoveDuplicates( 
        valuelist(HospitalVisits2.Reason_For_Visit, "|")
        ,"|"
        ,true 
    )
    ,", "
    ,"|"
    ,false 
) ;

Я знаю, что это несколько строк, но я отформатировал этот способ, чтобы сделать его более понятным и потому что я ненавижу прокручиватьстраница.: -)

Чтобы взглянуть на то, что мы делаем:

Наш объект запроса - это столбец Reason_For_Visit запроса HospitalVisits2.Одной из самых старых функций CF для работы с запросами является valueList().По сути, он возьмет значения из столбца запроса (HospitalVisits2.Reason_For_Visit) и превратит этот элемент массива в список значений для этого столбца с разделителями (https://cfdocs.org/valuelist).). Он может принимать необязательный аргумент delimiter, который позволяет намчтобы изменить разделитель нашего списка. Я решил изменить значение по умолчанию , на |, так что если какой-либо из наших элементов будет иметь запятую, он не будет случайно случайно интерпретирован в списке.

Теперь, когда у нас есть | -ограниченный список Reason_For_Visit, мы можем использовать функцию List в этом списке, чтобы избавиться от дубликатов. Эта функция очень умно названа listRemoveDuplicates() (https://cfdocs.org/listremoveduplicates). Может принимать два необязательных аргумента: определенный разделитель списка и логическое значение того, следует ли игнорировать регистр строк в списке. Мы даем ему разделитель, который мы установили в valueList(), и сообщаем емуигнорировать регистр дубликатов, и у нас есть дедуплицированный список.

Теперь нам просто нужно изменить разделители в нашей строке, чтобы они не были |. К счастью, у Coldfusion есть еще один способФункция списка с именем rly, listChangeDelims() (https://cfdocs.org/listchangedelims). Эта функция принимает наш список и аргумент для нового разделителя, который мы хотим.По умолчанию это запятая.Он также принимает два необязательных аргумента.Мы можем указать, какой у нас текущий разделитель (|), и можем сказать, что мы хотим включить пустые значения.Здесь мы, вероятно, не хотим, чтобы эти пустые.Это может дать нам список вроде Thing1, Thing2,,Thing4.

valueList() является очень старым и будет в значительной степени использоваться в любой версии ColdFusion или даже в полусовместимом парсере CFML.listRemoveDuplicates() и listChangeDelims() были добавлены в CF10 и доступны в Lucee 4.5+.И, видимо, TryCF указывает, что он все еще будет работать в Railo 4.2.Если вы используете что-то старше этого, это будет немного сложнее и, вероятно, медленнее, чтобы удалить эти дупы.

Я создал пример на https://trycf.com/gist/8e3107959cc051dd264b850bbeae88e3/acf?theme=monokai. Вы также можете видеть, что эти функции будут обрабатывать пустой запрос, запрос только с одним элементом и запрос только с одним пустым элементом.Вы не получите случайных запятых.

Есть и другие способы сделать это, и я не уверен, как это будет масштабироваться с очень большим списком, но это будет работать довольно быстро.И этот метод было бы довольно легко изменить, если бы вам нужно было выполнить итерацию по нескольким пациентам для вывода их причин.В более новых версиях CF есть замыкания и другие вещи, которые можно использовать, чтобы сделать это немного быстрее.

=====================================================

РЕДАКТИРОВАТЬ: ИЗМЕНЕНО ДЛЯ CFMX

https://trycf.com/gist/91bc66f0fd0b7597e7a4652e9d255e41/acf?theme=monokai

Я должен отметить, что я нев настоящее время есть способ проверить что-то старое, как CFMX, так что я просто ухожу из памяти.Я не могу вспомнить, можно ли установить разделители в valueList() и structKeyList() в CFMX.Их можно удалить, и вы все равно получите список, разделенный запятыми.У него просто не будет лишнего пробела после запятой.Вам придется проверить.

По сути, вы можете перебрать свой запрос и построить структуру (которая не будет вставлять дубликаты ключей по своей природе), , но я увидел запятую там, когда пытался вывести список структурных ключей, что требовало дополнительныхобработка для удаления этой запятой .Поэтому я думаю, что более чистый способ может быть в состоянии циклически проходить по списку значений, а не циклически проходить по запросу.Я знаю, что цикл по списку будет медленнее, чем цикл по запросу, но я не уверен, насколько это повлияет на ваш масштаб.Я пошел с:

<!--- create the struct --->
<cfset newReasonStruct = StructNew() />

<!--- CF Structs will overwrite duplicate keys. ---> 
<!--- NOTE: I can't remember if delimiters were valid arguments for valuelist() in CFMX --->
<cfloop index="VisitReason" list="#valuelist(HospitalVisits2.Reason_For_Visit, "|")#" delimiters="|">
    <cfif len(trim(Reason_For_Visit))> <!--- Don't add empties. --->
        <cfset newReasonStruct[VisitReason] = "" > 
    </cfif>
</cfloop>

<!--- Set a variable for our new list. --->
<cfset newReasonList = StructKeyList(newReasonStruct,", ") >

This is our main query (with valuelist()): <cfoutput>#newReasonList#</cfoutput>

РЕДАКТИРОВАТЬ 2: Смотрите мой зачеркнутый выше.Я не думал.Первая запятая была вызвана пустым элементом в цикле запроса.Это привело к тому, что значение «ключа» стало пустой строкой, которая затем сортировалась в начало моей выходной строки.Метод цикла списка valueList() фильтровал этот пустой элемент, но цикл запроса не был.Таким образом, дополнительную обработку для обрезки ведущей запятой можно просто выполнить, переключившись на цикл запроса и не добавляя «ключ» в структуру, если она пуста.Однако это изменяется от одного набора функций cfif/right() в конце к функции len(trim()) для каждого цикла в запросе.Опять же, в зависимости от ваших данных, одна функция может быть более производительной, чем другая.Хотя это немного похоже на микрооптимизацию.

<!--- CF Structs will overwrite duplicate keys. ---> 
<cfloop query="HospitalVisits2">
    <cfif len(trim(Reason_For_Visit))> <!--- Don't add empties. --->
      <cfset newReasonStruct[Reason_For_Visit] = "" > 
    </cfif>
</cfloop>

https://trycf.com/gist/169e9e0a592bf88aac462cc3a6e0d2c6/acf?theme=monokai

0 голосов
/ 22 сентября 2018

Это запрос функции Lucee.Возможно, вы можете использовать примеры на этой странице:

https://luceeserver.atlassian.net/browse/LDEV-442

<cfscript>
s = "a string";
i = 42;
f = pi();
st1 = {key1="value1"};
st1bis = {key1="value1"};
st1ref = st1;
st2 = {key2="value2"};
a1 = [1];
a1bis = [1];
a1ref = a1;
a2 = [2];

base = [s,i,f,st1,st1bis,st1ref,st2,a1,a1bis,a1ref,a2,s,i,f,st1,st1bis,st1ref,st2,a1,a1bis,a1ref,a2];

function arrayRemoveDuplicates(array){
    return array.reduce(function(deduped, el){
        return deduped.find(el) ? deduped : deduped.append(el);
    }, []);
}

writeDump(var=base, label="original")
writeDump(var=arrayRemoveDuplicates(base), label="deduped")
</cfscript>
...