Как вы можете проверить, совпадают ли два массива с использованием CFML? - PullRequest
3 голосов
/ 27 августа 2008

Используя CFML (ColdFusion Markup Langauge, он же ColdFusion), как вы можете сравнить, если два одномерных массива одинаковы?

Ответы [ 7 ]

11 голосов
/ 27 августа 2008

Существует очень простой способ сравнения двух массивов с использованием базовой Java-версии CFML. Согласно недавнему блогу Adobe Рупеша Кумара (http://coldfused.blogspot.com/), Массивы ColdFusion представляют собой реализацию списков java (java.util.List). Таким образом, все методы списков Java доступны для массивов CFML.

Таким образом, чтобы сравнить 2 массива, все, что вам нужно сделать, это использовать метод equals. Он возвращает ДА, если массивы равны, и НЕТ, если они не равны.

<cfset array1 = listToArray("tom,dick,harry,phred")/>
<cfset array2 = listToArray("dick,harry,phred") />
<cfset array3 = listToArray("tom,dick,harry,phred")/>

<cfoutput>
Array2 equals Array1 #array2.equals(array1)# (returns a NO) <br/>
Array3 equals Array1 #array3.equals(array1)# (returns a YES) <br/>
</cfoutput>
3 голосов
/ 08 сентября 2008

Если исходить из ответа Джеймса, я подумал, что JSON может быть предпочтительнее WDDX. Фактически, это оказывается значительно более эффективным. Сравнение хешей не так дорого, но сериализация данных и последующая генерация хеша могут быть (для больших и / или более сложных структур данных).

<cfsilent>
    <!--- create some semi-complex test data --->
    <cfset data = StructNew() />
    <cfloop from="1" to="50" index="i">
        <cfif variables.i mod 2 eq 0>
            <cfset variables.data[variables.i] = StructNew()/>
            <cfset tmp = variables.data[variables.i] />
            <cfloop from="1" to="#variables.i#" index="j">
                <cfset variables.tmp[variables.j] = 1 - variables.j />
            </cfloop>
        <cfelseif variables.i mod 3 eq 0>
            <cfset variables.data[variables.i] = ArrayNew(1)/>
            <cfset tmp = variables.data[variables.i] />
            <cfloop from="1" to="#variables.i#" index="j">
                <cfset variables.tmp[variables.j] = variables.j mod 6 />
            </cfloop>
            <cfset variables.data[variables.i] = variables.tmp />
        <cfelse>
            <cfset variables.data[variables.i] = variables.i />
        </cfif>
    </cfloop>
</cfsilent>

<cftimer label="JSON" type="inline">
    <cfset jsonData = serializeJson(variables.data) />
    <cfset jsonHash = hash(variables.jsonData) />
    <cfoutput>
        JSON: done.<br />
        len=#len(variables.jsonData)#<br/>
        hash=#variables.jsonHash#<br />
    </cfoutput>
</cftimer>
<br/><br/>
<cftimer label="WDDX" type="inline">
    <cfwddx action="cfml2wddx" input="#variables.data#" output="wddx" />
    <cfset wddxHash = hash(variables.wddx) />
    <cfoutput>
        WDDX: done.<br />
        len=#len(variables.wddx)#<br/>
        hash=#variables.wddxHash#<br />
    </cfoutput>
</cftimer>

Вот вывод, который приведенный выше код генерирует на моей машине:

JSON: done.
len=7460
hash=5D0DC87FDF68ACA4F74F742528545B12
JSON: 0ms

WDDX: done.
len=33438
hash=94D9B792546A4B1F2FAF9C04FE6A00E1
WDDX: 47ms

Хотя структура данных, которую я сериализую, довольно сложна, ее легко можно считать небольшой. Это должно сделать эффективность сериализации JSON поверх WDDX еще более предпочтительной.

В любом случае, если бы я попытался написать метод «compareAnything» с использованием сравнения хешей, я бы использовал сериализацию JSON поверх WDDX.

2 голосов
/ 15 сентября 2008

Я некоторое время назад изучал использование нативных Java-объектов CF, и этот вопрос напомнил мне несколько постов в блоге, которые я добавил в закладки в результате своего поиска.

Массив ColdFusion фактически является реализацией списка java (java.util.List). Таким образом, все методы списка фактически доступны для Array. CF предоставляет большую часть функциональности списка с использованием функций Array, но с Java-списком возможно несколько вещей, которые вы не можете сделать напрямую с функциями CF.

  1. Объединить два массива
  2. Добавить массив в середине другого массива
  3. Поиск элемента в массиве
  4. Поиск в массиве 1, чтобы увидеть, все ли элементы массива 2 найдены
  5. Проверка на равенство
  6. Удалить элементы в массиве 1 из массива 2

От: http://coldfused.blogspot.com/2007/01/extend-cf-native-objects-harnessing.html

Другой ресурс, который я нашел, показывает, как вы можете использовать собственный класс Java Array для получения уникальных значений и для создания пользовательских функций сортировки, например, в случае, если вам нужно отсортировать массив дат.

http://www.barneyb.com/barneyblog/2008/05/08/use-coldfusion-use-java/

Эта вторая ссылка содержит ссылки на другие публикации, в которых автор показывает, как использовать другие классы Java для получения функциональности или скорости по сравнению с функциями CF.

2 голосов
/ 04 сентября 2008

Ответ Джейсона, безусловно, лучший, но кое-что из того, что я сделал раньше, - это сравнение хэшей объектов, сериализованных в WDDX.

Этот метод полезен только для сравнительно небольших массивов, но это еще один вариант, если вы хотите сохранить его чисто CFML. Преимущество также в том, что вы можете применять этот метод и к другим типам данных ...

Редактировать: Адамс совершенно прав (как вы можете видеть из его чисел) - JSON гораздо более экономичен не только в этой ситуации, но и для сериализации в целом. В свою защиту я застрял с использованием CFMX 6.1, который не имеет встроенных функций JSON и пытался избежать внешних библиотек.

2 голосов
/ 30 августа 2008

Пользовательская функция arrayCompare () в cflib должна это делать http://cflib.org/index.cfm?event=page.udfbyid&udfid=1210

1 голос
/ 25 сентября 2008

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

<cfif arrayToList(arrayA) IS arrayToList(arrayB)>
    Arrays are equal!
</cfif>

Не так элегантно, как другие решения, но очень просто.

1 голос
/ 17 сентября 2008

Все эти решения проверяют, что два массива равны. Они не проверяют, что это один и тот же объект. Единственный способ, которым я знаю, сделать это в нативном CF - это каким-то образом изменить объект и посмотреть, есть ли изменение в обеих ссылках.

Я также думаю, что вам следует опасаться, что CF реализует определенные классы Java или предоставляет методы. Они могут измениться.

Что касается сравнения двух массивов, чтобы увидеть, является ли содержимое одинаковым, почему бы не просто Проверьте длину (если отличается, верните false) Если длины одинаковы от 1 до массива len, проверьте, что элементы имеют одинаковый разрыв, и в противном случае верните false.

Это будет работать для простых значений.

...