Статьи

«Вы хотите сделать что?»

Хорошо, я знаю, что это не вторая часть моего CFC для обычного разработчика, но я хотел поделиться с вами кое-чем классным, что я сделал сегодня. У меня был запрос местоположений, которые нуждались в дополнительной строке, вставленной в это. Теперь это звучит как легкая вещь, но есть подвох, не всегда подвох. Мне нужно было, чтобы запрос сортировал местоположения по алфавиту, но эта новая строка, которую мне нужно было вставить, должна была быть первой в строке. Поэтому моей задачей было:

  1. Запросите базу данных и получите список всех местоположений и их соответствующих идентификаторов и упорядочите их в алфавитном порядке
  2. Вставьте в первую строку этого же запроса список для корпоративного офиса с идентификатором -99

Итак, вот мой запрос:

<cfquery name="getLocations" datasource="MyDSN">
     SELECT franchiseeName + ' (' + city + ', ' + stateProvince + ')' AS lookupdisplay, franchiseeid AS lookupkey
     FROM franchisee
ORDER BY lookupdisplay
</cfquery>

Это возвращает хороший набор результатов запроса с двумя столбцами lookupDisplay, который имеет мое имя / состояние местоположения и lookupKey, который имеет идентификатор для этого конкретного местоположения. Итак, как мне получить еще одну строку в этом запросе? Ну, добавить строку легко, мы можем просто сделать:

<cfset QueryAddRow(getLocations,1)>

Функция QueryAddRow будет вставлять одну пустую строку (изменение 1 на другое число будет вставлять это количество строк) в мой набор результатов getLocations . Нет, чтобы заполнить эту строку, мне нужно сделать следующее:

<cfset QuerySetCell(getLocations, 'lookupDisplay',Corporate Posting (Waco, TX)')>
<cfset QuerySetCell(getLocations, 'lookupkey','-99')>

Используя функцию QuerySetCell, я могу заполнить свои пустые строки, НО есть проблема с этим. Строка находится внизу моего запроса, и мне нужно, чтобы он был вверху. Моей первой мыслью было просто выполнить «Запрос запросов» и просто изменить порядок всего, НО моя добавленная стоимость начинается с C, и я знаю, что у меня есть местоположения, которые начинаются с A и B (всего около 8, если быть точным). Так что же делать разработчику? Ну, я начинаю думать о вещах (в частности, о структурах данных), которые легко перемешать. Для меня массивы — это самая простая структура данных, которую можно сортировать и манипулировать, но результаты запроса не являются простыми массивами. Они больше похожи на массивы со структурами в каждой позиции; каждая строка представляет собой массив позиций, а столбцы составляют структуру.

Итак, мне нужно написать код, который возьмет мой запрос и превратит его в массив структур. Легко ли? Конечно, спасибо www.cflib.org ! Если вы никогда не были в CFlib, вам нужно идти туда прямо сейчас , это так круто! Это сайт, полный замечательных функций для некоторых простых и сложных вещей. Быстрый поиск в библиотеке манипулирования данными позволил мне получить две необходимые мне функции: ArrayOfStructuresToQuery (Дэвид Кроуфорд) и QueryToArrayOfStructures (Натан Динтенфасс).

С помощью этих двух функций я мог бы превратить мой запрос в один злой массив (вы должны попытаться вывести его и получить максимум для себя!), А затем я мог бы использовать некоторый код для сортировки последней записи по вертикали. Итак, мой следующий шаг после того, как мой запрос был создан и моя запись была добавлена ​​в него, это превратить мой запрос в массив структур, например:

<cfset getLocationsArray = QueryToArrayOfStructures(getLocations)>

Тогда я мог бы сделать CFLoop для этого массива и использовать функцию ArraySwap для создания моей сортировки пузырьков следующим образом:

 <cfloop index="j" from="1" to="#ArrayLen(getLocationsArray)#">
     <cfset ArraySwap(getLocationsArray,j,ArrayLen(getLocationsArray))>
</cfloop>

Позвольте мне разбить эти последние 3 строки для вас. Первая строка — это мой тег CFLoop, и, в частности, это цикл индекса, вы, программисты, будете знать, что это цикл FOR, но в ColdFusion это просто цикл индекса. Я установил свой индекс на j, который будет переменной, которую я могу использовать внутри своих тегов CFLoop. Атрибут from установлен в 1, помните, что массивы ColdFusion всегда начинаются с 1, в то время как большинство других языков начинаются с 0. Атрибут to фактически является результатом моей функции ArrayLen (), которая передается в результате выполнения функций QueryToArrayOfStructures, это Функция ArrayLen вернет числовое значение, равное количеству позиций массива, чтобы убедиться, что я не зациклен вне моего массива. Если бы я просто установил атрибут to, чтобы сказать 50, но имел только 45 позиций массива, ColdFusion генерировал бы ошибку ArrayIndexOutOfBounds, в основном говоря мне, что я устал ссылаться на то, что не существует.

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

Итак, давайте предположим, что мой массив имеет только 5 позиций и выглядит примерно так:

getLocationsArray [1] = Структура A
getLocationsArray [2] = Struct B
getLocationsArray [3] = Struct C
getLocationsArray [4] = Struct D
getLocationsArray [5] = Struct E

Теперь цель здесь — сделать так, чтобы Struct E был на вершине, а затем все остальное переместилось на A — D. Так что в конце моего первого прохода в моем CFLoop мой массив будет выглядеть так:

getLocationsArray [1] = Struct E
getLocationsArray [2] = Struct B
getLocationsArray [3] = Struct C
getLocationsArray [4] = Struct D
getLocationsArray [5] = Структура A

Проход № 2 заменит то, что находится в положении 2, на то, что находится в положении 5

getLocationsArray [1] = Struct E
getLocationsArray [2] = Структура A
getLocationsArray [3] = Struct C
getLocationsArray [4] = Struct D
getLocationsArray [5] = Struct B

Проход № 3 поменяет позицию 3 с позиции 5

getLocationsArray [1] = Struct E
getLocationsArray [2] = Структура A
getLocationsArray [3] = Структура B
getLocationsArray [4] = Struct D
getLocationsArray [5] = Struct C

Проход № 4 поменяет позицию 4 с позиции 5

getLocationsArray [1] = Struct E
getLocationsArray [2] = Структура A
getLocationsArray [3] = Структура B
getLocationsArray [4] = Struct C
getLocationsArray [5] = Struct D

Теперь на этом этапе это хорошо, но наш цикл в том виде, в каком он сейчас закодирован, сделает еще один обмен между позицией 5 и позицией 5, что ничего не даст.

Итак, теперь вы можете видеть, что у меня есть именно то, что мне нужно. Самое замечательное в этом — если мне нужно, чтобы оно появилось в позиции 3, все, что мне нужно сделать, это изменить значение в моем CFLoop на 3, и произойдет то же самое, но оно будет работать с 3 до 5.

Хорошо, теперь, когда все так, как я хочу, мне просто нужно превратить его обратно в набор результатов запроса, используя:

<cfset getLocations = ArrayOfStructuresToQuery(getLocationsArray)>

Использование функции ArrayOfStructuresToQuery возвращает меня к моему запросу, который теперь содержит данные в том порядке, в котором я их хотел.

Не потрепаться, да? Как бы вы подошли к проблеме?