Поскольку вы, вероятно, сталкиваетесь с более сложными структурами данных, такими как этот массив, я бы расширил решение.
Более вместительная версия на основе @ ege-Özcan очень симпатичного ответа .
blockquote>Проблема
Я столкнулся с ниже и не мог ее изменить. Я также не хотел временно сгладить объект. Я также не хотел использовать underscore / lodash, главным образом по соображениям производительности и забавой для его реализации.
var People = [ {Name: {name: "Name", surname: "Surname"}, Middlename: "JJ"}, {Name: {name: "AAA", surname: "ZZZ"}, Middlename:"Abrams"}, {Name: {name: "Name", surname: "AAA"}, Middlename: "Wars"} ];
Цель
Цель состоит в том, чтобы отсортировать ее в основном с помощью
People.Name.name
и, во-вторых,People.Name.surname
Препятствия
Теперь в базовом решении используется скобка для вычисления свойств для динамического сортировки. Здесь, однако, нам также придется динамически создавать условные обозначения скобок, так как вы ожидаете, что некоторые из них
People['Name.name']
будут работать, а это не так.С другой стороны, выполнение
People['Name']['name']
является статическим и позволяет вам спуститься на n -й уровень.Решение
Основным дополнением здесь будет спуск по дереву объектов и определение значения последнего листа, вы должны указать, а также любой промежуточный лист.
var People = [ {Name: {name: "Name", surname: "Surname"}, Middlename: "JJ"}, {Name: {name: "AAA", surname: "ZZZ"}, Middlename:"Abrams"}, {Name: {name: "Name", surname: "AAA"}, Middlename: "Wars"} ]; People.sort(dynamicMultiSort(['Name','name'], ['Name', '-surname'])); // Results in... // [ { Name: { name: 'AAA', surname: 'ZZZ' }, Middlename: 'Abrams' }, // { Name: { name: 'Name', surname: 'Surname' }, Middlename: 'JJ' }, // { Name: { name: 'Name', surname: 'AAA' }, Middlename: 'Wars' } ] // same logic as above, but strong deviation for dynamic properties function dynamicSort(properties) { var sortOrder = 1; // determine sort order by checking sign of last element of array if(properties[properties.length - 1][0] === "-") { sortOrder = -1; // Chop off sign properties[properties.length - 1] = properties[properties.length - 1].substr(1); } return function (a,b) { propertyOfA = recurseObjProp(a, properties) propertyOfB = recurseObjProp(b, properties) var result = (propertyOfA < propertyOfB) ? -1 : (propertyOfA > propertyOfB) ? 1 : 0; return result * sortOrder; }; } /** * Takes an object and recurses down the tree to a target leaf and returns it value * @param {Object} root - Object to be traversed. * @param {Array} leafs - Array of downwards traversal. To access the value: {parent:{ child: 'value'}} -> ['parent','child'] * @param {Number} index - Must not be set, since it is implicit. * @return {String|Number} The property, which is to be compared by sort. */ function recurseObjProp(root, leafs, index) { index ? index : index = 0 var upper = root // walk down one level lower = upper[leafs[index]] // Check if last leaf has been hit by having gone one step too far. // If so, return result from last step. if (!lower) { return upper } // Else: recurse! index++ // HINT: Bug was here, for not explicitly returning function // https://stackoverflow.com/a/17528613/3580261 return recurseObjProp(lower, leafs, index) } /** * Multi-sort your array by a set of properties * @param {...Array} Arrays to access values in the form of: {parent:{ child: 'value'}} -> ['parent','child'] * @return {Number} Number - number for sort algorithm */ function dynamicMultiSort() { var args = Array.prototype.slice.call(arguments); // slight deviation to base return function (a, b) { var i = 0, result = 0, numberOfProperties = args.length; // REVIEW: slightly verbose; maybe no way around because of `.sort`-'s nature // Consider: `.forEach()` while(result === 0 && i < numberOfProperties) { result = dynamicSort(args[i])(a, b); i++; } return result; } }
Пример
Рабочий пример в JSBin
Уже пару месяцев я использую Command-T vim plugin Винсента Колаюты. Винсент написал те его части, которые должны быть быстрыми, на C, и я должен сказать, что так оно и есть! И я думаю, что его логика сопоставления шаблонов файлов даже лучше, чем Command-T от Textmate. Посмотрите скринкаст.
Плагин Command-T для VIM обеспечивает чрезвычайно быстрый, интуитивно понятный механизм для открытия файлов с минимальным минимальным количеством нажатий клавиш. Он назван "Command-T", потому что он вдохновлен окно "Перейти к файлу", привязанное к Command-T в TextMate.
Файлы выбираются путем ввода символы, которые появляются в их путях, и упорядочиваются алгоритмом, который знает, что символы, появляющиеся в определенных местах (например, сразу после разделителя путей) должны иметь больший вес.
Более простое переключение буферов содержит много полезных советов. Я адаптировал следующее в свой .vimrc, который делает автозаполнение имен буферов, сопоставляет наиболее полезные команды переключения буферов с клавишами
"" Tab triggers buffer-name auto-completion
set wildchar=<Tab> wildmenu wildmode=full
let mapleader = ","
map <Leader>t :CommandT<Return>
map <Leader>a :bprev<Return>
map <Leader>s :bnext<Return>
map <Leader>d :bd<Return>
map <Leader>f :b
"" Show the buffer number in the status line.
set laststatus=2 statusline=%02n:%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P
Я также использую MiniBufExplorer, который предоставляет компактный список каждого перечисленного буфера в его собственном горизонтальном разделении вверху.
Превосходное Буферный Проводник , быть добрался, чтобы быть такой сильной памятью мышц, которую я желаю, что я мог использовать его в других приложениях. Я нахожу, что он чрезвычайно быстр, активно редактируя больше чем два файла.
я использую простой: vsplit с ^W+w/^W+r и: tabnew с сочетаниями клавиш Ctrl+Alt+PgUp/PgDown.
imap <A-1> <Esc>:tabn 1<CR>i
imap <A-2> <Esc>:tabn 2<CR>i
imap <A-3> <Esc>:tabn 3<CR>i
imap <A-4> <Esc>:tabn 4<CR>i
imap <A-5> <Esc>:tabn 5<CR>i
imap <A-6> <Esc>:tabn 6<CR>i
imap <A-7> <Esc>:tabn 7<CR>i
imap <A-8> <Esc>:tabn 8<CR>i
imap <A-9> <Esc>:tabn 9<CR>i
map <A-1> :tabn 1<CR>
map <A-2> :tabn 2<CR>
map <A-3> :tabn 3<CR>
map <A-4> :tabn 4<CR>
map <A-5> :tabn 5<CR>
map <A-6> :tabn 6<CR>
map <A-7> :tabn 7<CR>
map <A-8> :tabn 8<CR>
map <A-9> :tabn 9<CR>
Мне нравится, "когда ctrl-w s" и "ctlr-w v" разделяет окно. Тогда я отображаю ключи перемещения (h, j, k, l) с ctrl, удерживаемым для перемещения между окнами с несколькими панелями:
" Map ctrl-movement keys to window switching
map <C-k> <C-w><Up>
map <C-j> <C-w><Down>
map <C-l> <C-w><Right>
map <C-h> <C-w><Left>
Необходимость двигать моей рукой к клавишам со стрелками является раздражающей.
Затем, я настроил ctlr-вкладку для переключения между буферами в текущее окно (как много других сред):
" Switch to alternate file
map <C-Tab> :bnext<cr>
map <C-S-Tab> :bprevious<cr>
Они работали вполне прилично на меня за прошлые несколько лет, хотя энергия всегда имеет больше секретов, чем можно знать.
Я использую основы -' :ls
' +' :bn
' / ':bp
' +' :b <part-of-name>
'
Я раньше использовал комбинацию вкладок и нескольких gvim экземпляров, сохраняя группы связанных файлов как вкладки в каждом экземпляре. Пока я не закончил со слишком многими вкладками в одном экземпляре, панель вкладок показывает Вам название каждого файла, который Вы редактируете сразу.
Тогда я читал сообщение Jamis Buck о том, как он переключился от TextMate назад к энергии и изучил некоторые большие приемы:
Теперь я просто имею один gvim экземпляр, максимизируемый, и разделяю его на несколько окон, таким образом, я вижу несколько файлов сразу. Я связал Ctrl-F с fuzzyfinder_textmate, поэтому теперь, если я ввожу (говорит) Ctrl-F mod/usob
, это открывает app/models/user_observer.rb. Я почти никогда не беспокоюсь вкладками больше.
2010/08/07
Обновления, В то время как fuzzyfinder_textmate остается потрясающим как Кейси, указывает в комментариях, это больше не сохраняется. Кроме того, это (и/или fuzzyfinder.vim) становится немного медленным и нестабильным при работе с крупными проектами (много каталогов или файлов), таким образом, я искал альтернативу.
, К счастью, кажется, существует очень хорошая альтернатива в форме плагин Команды-T Wincent Colaiuta . Это имеет очень похожий (если не немного лучше) поведение к fuzzyfinder_textmate, но заметно быстрее; это также имеет хорошие функции как способность открыть найденный файл в разделении или вертикальном разделении. Спасибо (и upvotes!) David Rivers для того, чтобы указывать на него.
Я провел долгое время, создавая мой .vimrc для работы с этим HTML:: проект Масона я шел в течение четырех лет, таким образом, у меня есть нечетное соединение вкладок и окон с несколькими панелями. Для Вашего удовольствия просмотра:
map ;o :Sex <CR>
map <C-J> <C-W>j
map <C-K> <C-W>k
map <C-l> <C-W>l
map <C-h> <C-W>h
map ;] :tabnext<CR>
map ;[ :tabprev<CR>
map <C-t> :tabe +"browse ."<CR>
map <C-O> :NERDTreeToggle ~/curr/trunk/<CR>
Я использую tselectbuffer. Это действительно быстро, и в отличие от bufexplorer не занимает место в Вашем окне. Это также имеет возрастающий поиск. Я попробовал minibufexplorer, и я нашел навигацию в буфере немного трудной.