Как удалить повторяющиеся значения из массива Coldfusion? - PullRequest
10 голосов
/ 26 мая 2011

У меня есть функция, которая получает строку тегов.Чтобы сохранить теги по отдельности, функция преобразует строку в массив:

this.tags = listToArray(this.tags, ", ");

Как удалить дублирующиеся значения в случае их появления?

Ответы [ 9 ]

18 голосов
/ 26 мая 2011

Мне нравится использовать Java для такого рода задач:

<cfset tags = "apples,oranges,bananas,pears,apples" />

<cfset tagsArray = createObject("java", "java.util.HashSet").init(ListToArray(tags)).toArray() />

<cfdump var="#tags#" />
<cfdump var="#tagsArray#" />

Единственная проблема в том, что он учитывает регистр, поэтому думает, что «яблоки» и «яблоки» - это разные вещи (что технически да, в зависимости от вашей системы может отличаться). Обходной путь - сначала прописать все в списке.

10 голосов
/ 26 мая 2011

Простой способ удалить дубликаты из списка - сначала преобразовать список в структуру, а затем преобразовать структуру в массив.Однако, если порядок элементов в списке важен, это может быть неуместно, так как элементы в структуре будут отсортированы.

Если порядок элементов важен, вам нужно будет создать массив вручную, а не использоватьфункция listToArray.

<!--- CF9 --->
<cfset tags = "apples,oranges,bananas,pears,APPLES" />
<cfset tagArray = arrayNew(1) />

<cfloop list="#tags#" index="tag" delimiters=",">
    <cfif not ArrayFindNoCase(tagArray,tag)>
        <cfset arrayAppend(tagArray, tag) />
    </cfif>
</cfloop>
4 голосов
/ 27 февраля 2014

Поскольку вы действительно начинаете со строки / списка, который затем преобразовываете в массив, вы можете передать строку через ListRemoveDuplicates перед преобразованием в массив.ListRemoveDuplicates был введен в Coldfusion 10;входные параметры (list, delimiter = ",", ignoreCase = FALSE).

this.tags = listToArray(listRemoveDuplicates(arrayInput,", ",TRUE));

Если вы на самом деле начинали с массива, вам нужно сначала преобразовать его в список, а затем обратнопосле.

this.tags = listToArray(listRemoveDuplicates(arrayToList(arrayInput),", ",TRUE) );
2 голосов
/ 09 декабря 2011

Мне просто пришлось расшифровать очень большой список (5k + записей) и найти гораздо более быстрый способ, чем использование цикла. Я чувствую необходимость поделиться.

  1. преобразовать список в массив (у вас уже есть массив, поэтому пропустите) <cfset thisArray = ListToArray(thisList)>
  2. Создать запрос с queryNew ("") <cfset thisQuery = QueryNew("")>
  3. Добавить столбец к этому запросу с массивом из шага 1 <cfset temp = QueryAddColumn(thisQuery,"items","varChar",thisArray)>
  4. Запрос различных значений <cfquery name="qItems" dbtype="query">SELECT DISTINCT items FROM thisQuery</cfquery>
  5. преобразовать результат в список <cfset returnString = ValueList(qItems.items)>
  6. Это простой шаг для преобразования этого списка обратно в массив

Я написал это в функцию для удобства использования:

<cffunction name="deDupList" output="no" returntype="string">
    <cfargument name="thisList" required="yes">
    <cfargument name="thisDelimeter" required="yes" default=",">
    <cfset var loc = StructNew()>

    <cfset loc.thisArray = ListToArray(thisList,thisDelimeter)>
    <cfset loc.thisQuery = QueryNew("")>
    <cfset loc.temp = QueryAddColumn(loc.thisQuery,"items","varChar",loc.thisArray)>
    <cfquery name="qItems" dbtype="query">
        SELECT DISTINCT items FROM loc.thisQuery
    </cfquery>
    <cfset loc.returnString = ValueList(qItems.items)>
    <cfreturn loc.returnString>
</cffunction>

Я сравнил его с несколькими другими методами, и вот результаты в миллисекундах:
Цикл проверки списка для> 1 экземпляра: 6265
Используя метод структуры Генри: 2969
Вышеуказанный метод: 31
Метод Джейсона: 30

2 голосов
/ 26 мая 2011

основано на идее Джейсона Хариту, но вы можете сделать это в чистом CF, используя Struct! (при сопоставлении ключей регистр не учитывается)

this.tags = listToArray(this.tags, ", ");
var tmpStruct = {};

for (var t in this.tags)
    tmpStruct[t] = "";

return structKeyArray(tmpStruct);

Однако для небольших списков я предпочитаю решение Антония.

1 голос
/ 01 июня 2017

Взяв ответ Джейсона чуть дальше, вот функция arrayDistinct.

function arrayDistinct (required array data) {
    var output = arrayNew(1);
    output.addAll(createObject("java", "java.util.HashSet").init(arguments.data));
    return output;
}

Вы можете проверить это здесь: https://trycf.com/gist/62ff904d4500519e3144fc9564d2bce7/acf

1 голос
/ 19 декабря 2012

В Coldfusion 10 или Railo 4 вы можете использовать функцию Underscore.cfc uniq () :

_ = new Underscore();

uniqueArray = _.uniq(arrayWithDuplicates);

Одним из преимуществ uniq() является то, что он позволяет вам при необходимости передать функцию преобразования.

Примечание: я написал Underscore.cfc

1 голос
/ 09 декабря 2011

Просто поместите массив в Struct, а затем скопируйте его обратно в массив;)

http://www.bennadel.com/blog/432-Using-ColdFusion-Structures-To-Remove-Duplicate-List-Values.htm

0 голосов
/ 07 июня 2011

На CFLib есть несколько UDF, которые делают это, ArrayyDiff (http://www.cflib.org/udf/arrayDiff) и ArrayCompare (http://www.cflib.org/udf/arrayCompare).

)

НТН, Larry

...