From 11d9b63dbaccca0d546f9cf9206d3b4f249716e6 Mon Sep 17 00:00:00 2001 From: rlx <0x0073@0x2620.org> Date: Wed, 11 Jan 2012 16:17:06 +0530 Subject: [PATCH] add Ox.sortBy --- source/Ox.UI/js/Video/Ox.AnnotationPanel.js | 6 +- source/Ox/js/Array.js | 136 ++++++++++++++------ 2 files changed, 98 insertions(+), 44 deletions(-) diff --git a/source/Ox.UI/js/Video/Ox.AnnotationPanel.js b/source/Ox.UI/js/Video/Ox.AnnotationPanel.js index 53189ef4..c3419f3e 100644 --- a/source/Ox.UI/js/Video/Ox.AnnotationPanel.js +++ b/source/Ox.UI/js/Video/Ox.AnnotationPanel.js @@ -156,9 +156,9 @@ Ox.AnnotationPanel = function(options, self) { self.setOption = function(key, value) { if (['in', 'out'].indexOf(key) > -1 && self.editing) { - var index = Ox.getIndexById(self.options.items, self.options.selected); - self.options.items[index][key] = value; - self.options.items[index].duration = self.options.out - self.options['in']; + var item = Ox.getObjectById(self.options.items, self.options.selected); + items[key] = value; + items.duration = self.options.out - self.options['in']; } if (key == 'in') { //fixme: array editable should support item updates while editing diff --git a/source/Ox/js/Array.js b/source/Ox/js/Array.js index dc6871c6..d93e36c3 100644 --- a/source/Ox/js/Array.js +++ b/source/Ox/js/Array.js @@ -83,47 +83,101 @@ Ox.range = function() { return arr; }; -/*@ -Ox.sort Sorts an array, handling leading digits and ignoring capitalization - arr Array - fn Optional map function that returns the value for the array element - > Ox.sort(['10', '9', 'B', 'a']) - ['9', '10', 'a', 'B'] - > Ox.sort([{id: 0, name: '80 Days'}, {id: 1, name: '8 Women'}], function(v) {return v.name}); - [{id: 1, name: '8 Women'}, {id: 0, name: '80 Days'}] -@*/ -Ox.sort = function(arr, fn) { - var len, matches = {}, sort = {}, - values = fn ? arr.map(fn) : arr; - // find leading numbers - values.forEach(function(val, i) { - var match = /^\d+/.exec(val); - matches[val] = match ? match[0] : ''; - }); - // get length of longest leading number - len = Ox.max(Ox.map(matches, function(val) { - return val.length; - })); - // pad leading numbers, and make lower case - values.forEach(function(val) { - sort[val] = ( - matches[val] ? Ox.pad( - matches[val], len - ) + val.toString().substr(matches[val].length) : val - ).toLowerCase(); - }); - return arr.sort(function(a, b) { - a = fn ? fn(a) : a; - b = fn ? fn(b) : b; - var ret = 0; - if (sort[a] < sort[b]) { - ret = -1; - } else if (sort[a] > sort[b]) { - ret = 1; - } - return ret; - }); -}; +(function() { + + function getSortValues(arr) { + var len, matches = {}, sort = {}; + // find leading numbers + arr.forEach(function(val) { + var match = /^\d+/.exec(val); + matches[val] = match ? match[0] : ''; + }); + // get length of longest leading number + len = Ox.max(Ox.map(matches, function(val) { + return val.length; + })); + // pad leading numbers and make lowercase + arr.forEach(function(val) { + sort[val] = ( + matches[val] + ? Ox.pad(matches[val], len) + + val.toString().substr(matches[val].length) + : val + ).toLowerCase(); + }); + return sort; + } + + /*@ + Ox.sort Sorts an array, handling leading digits and ignoring capitalization + (arr) -> Sorted array + (arr, fn) -> Sorted array + arr Array + fn Optional map function that returns the value for the array element + > Ox.sort(['10', '9', 'B', 'a']) + ['9', '10', 'a', 'B'] + > Ox.sort([{id: 0, name: '80 Days'}, {id: 1, name: '8 Women'}], function(v) {return v.name}) + [{id: 1, name: '8 Women'}, {id: 0, name: '80 Days'}] + @*/ + Ox.sort = function(arr, fn) { + var sort = getSortValues(fn ? arr.map(fn) : arr); + return arr.sort(function(a, b) { + a = fn ? fn(a) : a; + b = fn ? fn(b) : b; + var ret = 0; + if (sort[a] < sort[b]) { + ret = -1; + } else if (sort[a] > sort[b]) { + ret = 1; + } + return ret; + }); + }; + + /*@ + Ox.sortBy Sorts an array of objects by given properties + (arr, by) -> Sorted array + arr <[o]> Array of objects + by <[s]> Array of object properties (asc: 'foo' or '+foo', desc: '-foo') + > Ox.sortBy([{x: 1, y: 1}, {x: 1, y: 2}, {x: 2, y: 2}], ['+x', '-y']) + [{x: 1, y: 2}, {x: 1, y: 1}, {x: 2, y: 2}] + > Ox.sortBy([{id: 0, name: '80 Days'}, {id: 1, name: '8 Women'}], ['name']) + [{id: 1, name: '8 Women'}, {id: 0, name: '80 Days'}] + @*/ + Ox.sortBy = function(arr, by) { + var length = by.length, values = {}; + by = by.map(function(v) { + return { + key: v.replace(/^[\+\-]/g, ''), + operator: v[0] == '-' ? '-' : '+' + }; + }); + by.map(function(v) { + return v.key + }).forEach(function(key) { + values[key] = getSortValues(arr.map(function(v) { + return v[key]; + })); + }); + return arr.sort(function(a, b) { + var aValue, bValue, index = 0, key, ret = 0; + while (ret == 0 && index < length) { + key = by[index].key; + aValue = values[key][a[key]]; + bValue = values[key][b[key]]; + if (aValue < bValue) { + ret = by[index].operator == '+' ? -1 : 1; + } else if (aValue > bValue) { + ret = by[index].operator == '+' ? 1 : -1; + } else { + index++; + } + } + return ret; + }); + }; + +}()); /*@ Ox.unique Returns an array without duplicate values