2012-04-27 3 views
0

У меня есть массив объектов. Я хочу найти «максимум» этого массива на основе функции, которая возвращает какой-либо объект больше при задании двух объектов.Максимальное значение в массиве, основанное на функции

function comparison(first, second) { 
    // ... arbitrary comparison based on properties... 
    return first; // or second 
} 

var a = [obj1, obj2, obj3]; 
var maxObj = ????(comparison); 

Что я могу заполнить здесь? Что элегантно и коротко?

ответ

2

Что-то, как это должно быть быстрее, чем-то (в зависимости от данных):

/* 
    values: array of values to test. 
     fn: function that takes two arguements and returns true if the first is bigger. 
*/ 
var maximum = function(values, fn) { 
    var currentValue, maxValue = values.pop(); 
    while(values.length) 
     maxValue = fn(maxValue, currentValue = values.pop()) ? maxValue : currentValue; 
    return maxValue; 
} 

Примеры: http://jsfiddle.net/SaBJ4/2/

Еще лучше использовать Array.reduce:

var a = ['abc', 'defg', 'highlkasd', 'ac', 'asdh']; 
a.reduce(function(a, b) { return a.length > b.length ? a : b; }); // highlkasd 
+2

Недостатком является то, что эта функция изменяет свой вход, что может быть или не быть проблемой. –

+0

+1 для 'reduce', но вам понадобятся специальные массивы и массивы специального случая с одним элементом (в зависимости от поведения' сравнения'), используя явное начальное значение. –

+0

Ах сокращение было тем, что я искал. Благодаря! –

0
[obj,obj,obj].sort(comparison) 

// aka 
var sorted = [obj,obj,obj].sort(function(a,b){ 
    // return 1/0/-1 
}); 

Затем либо вытащите верхний, либо нижний элемент (однако, вы сортируете), чтобы получить объект «max».

Array.Sort

+0

[Примитивный пример] (http://jsfiddle.net/Ze86B/) –

+0

Это эффективно, но неэффективно; нахождение max должно быть O (n), тогда как это O (n^2) (худший случай). – Phrogz

1

Что не так с очевидным подходом?

for(var i = 0, max; i < a.length; ++i) 
    max = typeof max == 'undefined' ? a[i] : comparison(a[i], max); 

Оберните это, как вам нравится.


Или вы можете воспользоваться тем, что a = []; x = a[0] оставляет вас с undefined в x и сделать это путь RobG в:

for(var i = 1, max = a[0]; i < a.length; ++i) 
    max = comparison(a[i], max); 

Это хорошо избегает кучу typeof операторов и сравнений, которые вы действительно дон Не нужно.

+2

Почему бы не инициализировать 'max' как' a [0] 'и' i' как '1' и избежать тройного выражения? – RobG

+0

@mu * румянец * Конечно, вы правы; что совсем не относится к этому делу. Удаление моего глупого комментария. – Phrogz

+0

@RobG: Это отличная идея и даже ведет себя правильно, когда массив пуст, я думаю, у меня все еще есть старые привычки от C. –

Смежные вопросы