Объединив динамическое решение Ege с идеей Vinay, вы получите хорошее надежное решение:
Array.prototype.sortBy = function() {
function _sortByAttr(attr) {
var sortOrder = 1;
if (attr[0] == "-") {
sortOrder = -1;
attr = attr.substr(1);
}
return function(a, b) {
var result = (a[attr] < b[attr]) ? -1 : (a[attr] > b[attr]) ? 1 : 0;
return result * sortOrder;
}
}
function _getSortFunc() {
if (arguments.length == 0) {
throw "Zero length arguments not allowed for Array.sortBy()";
}
var args = arguments;
return function(a, b) {
for (var result = 0, i = 0; result == 0 && i < args.length; i++) {
result = _sortByAttr(args[i])(a, b);
}
return result;
}
}
return this.sort(_getSortFunc.apply(null, arguments));
}
Использование:
// Utility for printing objects
Array.prototype.print = function(title) {
console.log("************************************************************************");
console.log("**** "+title);
console.log("************************************************************************");
for (var i = 0; i < this.length; i++) {
console.log("Name: "+this[i].FirstName, this[i].LastName, "Age: "+this[i].Age);
}
}
// Setup sample data
var arrObj = [
{FirstName: "Zach", LastName: "Emergency", Age: 35},
{FirstName: "Nancy", LastName: "Nurse", Age: 27},
{FirstName: "Ethel", LastName: "Emergency", Age: 42},
{FirstName: "Nina", LastName: "Nurse", Age: 48},
{FirstName: "Anthony", LastName: "Emergency", Age: 44},
{FirstName: "Nina", LastName: "Nurse", Age: 32},
{FirstName: "Ed", LastName: "Emergency", Age: 28},
{FirstName: "Peter", LastName: "Physician", Age: 58},
{FirstName: "Al", LastName: "Emergency", Age: 51},
{FirstName: "Ruth", LastName: "Registration", Age: 62},
{FirstName: "Ed", LastName: "Emergency", Age: 38},
{FirstName: "Tammy", LastName: "Triage", Age: 29},
{FirstName: "Alan", LastName: "Emergency", Age: 60},
{FirstName: "Nina", LastName: "Nurse", Age: 54}
];
//Unit Tests
arrObj.sortBy("LastName").print("LastName Ascending");
arrObj.sortBy("-LastName").print("LastName Descending");
arrObj.sortBy("LastName", "FirstName", "-Age").print("LastName Ascending, FirstName Ascending, Age Descending");
arrObj.sortBy("-FirstName", "Age").print("FirstName Descending, Age Ascending");
arrObj.sortBy("-Age").print("Age Descending");
Одна вещь, что я видел это, уменьшает поврежденные фиксации, должен иметь хорошие сценарии перед фиксацией. Например, можно выполнить любые модульные тесты, прежде чем изменение будет фиксироваться. Это заставит фиксации быть немного медленными, но Вы экономите время путем предотвращения ступающий на чьи-то пальцы ног и имеющий необходимость принести извинения. Конечно, это становится намного более твердым справиться, когда у Вас есть многочисленная группа разработчиков и очень частые фиксации.
Один из примеров интеграции со средством отслеживания ошибки и осуществлением политики фиксации мог быть Trac svn пред/постфиксировать сценарии рычага, которые могут отказаться от фиксации, если сообщение о фиксации не ссылается ни на какой билет в средстве отслеживания ошибки и добавляет комментарии к существующим билетам на основе содержимого сообщения (т.е. сообщение о фиксации может содержать что-то как, "Фиксирует № 1, № 2 и № 8", где № 1, № 2, № 8 является числами билетов).
Поощряют частые фиксации. Товарищи по команде, плохо знакомые с управлением версиями, могут чувствовать, что они должны не допустить код в репозиторий, пока "это не работает правильно". Учите всех фиксировать рано и часто находить проблемы как можно скорее. Вместо того, чтобы держать код, 'пока это не работает, предложите, чтобы Ваши товарищи по команде создали ответвления для функции, которая могла бы повредить соединительную линию. Это приводит к...
Устанавливают ветвление и метки практики. В дополнение к ответвлениям для функций, поощрите своих товарищей по команде использовать ответвления для больших исправлений ошибок. Отметьте главные исправления ошибок вначале и конец работы. Поддержите теги (и возможно переходит) для выпусков производства/обеспечения качества.
Устанавливают политику для соединительной линии и придерживаются его. Один пример мог бы быть, "соединительная линия должна всегда создавать без ошибок". или "соединительная линия должна всегда передавать все модульные тесты". Любая работа, которая еще не может соответствовать стандартам соединительной линии, должна быть сделана в ответвлении.
Помимо переходящих политик и др. (где один размер определенно не соответствует всем), у Вас должны быть хорошие фиксации:
Золотое правило для управления исходным кодом: Регистрация Рано, Регистрация Часто
Для подсказок, как организовать Ваш репозиторий:
Консультируйтесь со своей командой об их изменениях, или по крайней мере посмотрите на разность очень тщательно, прежде, чем зафиксировать любые конфликты слияния. Попросите, чтобы они рассмотрели объединенный, кодируют себя, чтобы удостовериться, что их дополнения не были потеряны в слиянии.
Это делает его намного легче при использовании хороших инструментов, которые интегрируются хорошо с SVN. Они облегчают видеть то, что было изменено и тогда фиксировать все или часть Ваших изменений и часто обновлять Вашу рабочую копию к последней версии в SVN.
я рекомендую черепаха SVN (Если Вы используете Windows), и Визуальный SVN (при использовании VS).
Также видят, можно ли настроить его так, чтобы Вы получили электронное письмо или подобное уведомление любое время, изменение фиксируется (обычно также включая сообщение о фиксации и список измененных файлов). Сервисы как предложение CVSDude это. Я нахожу полезным знать и что обновление было сделано и затем иметь некоторую идею того, что содержится в том обновлении прежде, чем обновить мою рабочую копию.
Узнайте о переходящих и объединяющихся инструментах и соглашениях SVN.
лучший способ работать с другими членами команды состоит в том, чтобы разбиться, работа в полную разработку показывает/устраняет, затем работайте над отдельными изменениями, каждым в ответвлении. Тогда объедините изменения назад в ответвлении/соединительной линии магистрали, когда завершился/подготовил/утвердил, чтобы быть объединенным в.
Этот путь люди могут работать для общей цели (или на том же ответвлении или разделить ответвления), не сталкиваясь с другими изменениями.
Ваш пробег может варьироваться, и это может быть излишеством только для приблизительно двух человек.
Используйте интеграцию со своим программным обеспечением отслеживания ошибок. Если Вы используете Bugzilla, можно настроить его поэтому, если комментарий начинается "с Ошибки, XXXX" комментариев SVN автоматически добавляются как комментарий к данной ошибке, включая ссылку на Вас веб-интерфейс SVN к тому пересмотру.
Одна вещь, которую я нашел очень полезными, свойство svn:external , что означает, что можно сослаться на каталоги из других репозиториев в собственное. Это, дает действительно хорошие способы организовать Ваш код и данные. Некоторые примеры:
SVN отдельно является хорошим началом, и некоторые из других плакатов предложили некоторые большие предложения на лучших практиках.
единственная вещь, которую я добавил бы, состоит в том, что необходимо быть присоединением SVN с CruiseControl или TeamCity для управления Непрерывным Процессом интеграции. Это пошлет электронные письма сборки и сообщит всем, когда кто-то повредил сборку.
Это будет говорить о многом вначале, кто следует за Вашим процессом и кто не. Мог бы привести к некоторому трению, но Ваша команда будет более обеспечена в конечном счете.
Ну, основы:
Ответы, которые дают люди, являются большими. Большая часть этого получена в итоге в svn пользовательском документе для лучшие практики для SVN.
Для повторения:
Много уже было упомянуто, и здесь является еще немного:
, Если у Вас есть файлы, которые Вы не хотите в управлении исходным кодом (например, конфигурация, скомпилированные файлы, и т.д.), добавляют их к черный список . Таким образом, Вы замечаете любые файлы, которые Вы забываете добавлять, всегда ожидая пустой список файлов, показывающих как неизвестный SVN.
Добавляют событие фиксации сообщения, которое послало бы электронное письмо Вашему списку рассылки разработчика (или одно специфичное для этой цели) касающийся зафиксированного изменения и идеально патча для него.
Интегрируются с Вашим средством отслеживания ошибки так, чтобы ссылки на фиксации обнаружились на ошибках / запросы новых функций со ссылками на diffs. Средства отслеживания ошибки как поддержка MantisBT это.
Рассматривают интеграцию с [1 117] непрерывная интеграция (например, CruiseControl.NET ), NAnt для Сборки, и NUnit / VS для модульных тестов. Этот путь однажды пользовательский код регистраций или на запланированном интервале, код компилируется, модульные тесты, выполняется, и разработчик получает обратную связь процесса. Это также предупредило бы остальную часть команды, если репозиторий повреждается (т.е. не создает).
Одно из ключевых понятий, которым я всегда остаюсь верным, к , связанный с фиксацией код изменяется вместе . Заключение , не фиксируют несвязанных изменений кода в той же фиксации . Это означает, не исправляют 2 ошибки в одной фиксации (если это не то же, фиксируют), и не фиксируйте половину исправления ошибки в каждой из 2 фиксаций. Кроме того, если я должен добавить некоторое новое улучшение или что-то к несвязанной части системы, в которой я тогда нуждаюсь для некоторой другой работы, я фиксирую улучшение отдельно (и сначала). Идея состоит в том, что любое изменение, которое любой мог бы очевидно хотеть иметь самостоятельно (или откатывать самостоятельно) должно быть отдельной фиксацией. Это сохранит Вас тонны головных болей, когда это прибудет время, чтобы сделать слияния или откатывать поврежденные функции.
не фиксируют изменений форматирования с изменениями кода
, Если Вы хотите реструктурировать пробел гигантского файла ( Управление + K + D ), прекрасный. Фиксируйте изменение форматирования отдельно от фактического логического изменения. То же идет, если Вы хотите переместить функции в файлах. Фиксируйте перемещение отдельно от фактического редактирования.
Используйте это для шаблона комментариев:
[задача / история xxx] [второстепенная / основная] [комментарий] [дополнительный комментарий] [URL-адрес ошибки]