2012-02-22 2 views
1

Я стучал головой о стену, пытаясь решить эту проблему ... В принципе, у меня есть объект со структурой, подобную этой:Расширенный объект сортировки

results = { 
    1 : { 
    url : '/', 
    matches: { 
     title : true, 
     h1 : false, 
     copy : 2 
    } 
    }, 
    2 : { 
    url : '/?id=2', 
    matches: { 
     title : true, 
     h1 : true, 
     copy : 0 
    } 
    }, 
    3 : { 
    url : '/id=3', 
    matches: { 
     title : false, 
     h1 : false, 
     copy : 6 
    } 
    } 
} 

Это является результатом устанавливаемое из пользовательский поиск. Мне нужны результаты, чтобы иметь вес для релевантности, основанный на совпадениях внутри объектов. Результаты должны быть отсортированы следующим образом:

  1. Результаты с match.title == true - самые лучшие результаты. Внутри этого подмножества match.h1, являющийся истинным, несет наибольший вес (самый верхний), за которым следует количество вхождений в копии страницы (matches.copy).

  2. Результаты, имеющие match.h1 == true, должны отображать следующий в представлении результатов, отсортированный по количеству вхождений в копии страницы (matches.copy).

  3. Результаты с match.title и matches.h1, которые являются ложными, сортируются по совпадениям. В порядке убывания.

Возможно ли это с текущей структурой объекта? Или мне нужно разделить его и перекрестно ссылаться на каждый поднабор? Г! Это так рано, а кофе не работает :(


EDIT:. Преобразованный результат установлен массив объектов Новая структура:

results = [ 
    { pageid: 1, url: '/', matches: { title: true, h1: false, copy: 2 } }, 
    { pageid: 2, url: '/?id=2', matches: { title: true, h1: true, copy: 0 } }, 
    { pageid: 3, url: '/?id=3', matches: { title: false, h1: false, copy: 6 } } 
] 

Сортировка по-прежнему спасаясь меня Раньше я делал простые варианты, но ничего подобного. Я столкнулся с LINQ, что кажется многообещающим, но у меня нет опыта его использования. Не уверен, что это правильное направление или нет.

+0

Сделать массив A объектов, определить функцию сортировки sf, вызвать функцию A.sort (sf). – jgroenen

ответ

5

Я рекомендую использовать вместо этого массив, который предназначен для упорядоченного списка.

Вы можете использовать .sort и предоставить функцию специального поиска: http://jsfiddle.net/uR4Jn/2/.

Сначала попробуйте передвинуть элемент, имеющий .title === true, если у другого элемента есть .title === false. В противном случае попробуйте переместить элемент, имеющий .h1 === true, если другой элемент имеет .h1 === false. Наконец, просто сортируйте по .copy. (И переместите элемент вниз в первых двух случаях, если верно противоположное.)

var results = [ 
    { 
    url : '/', 
    matches: { 
     title : true, 
     h1 : false, 
     copy : 2 
    } 
    }, 
    { 
    url : '/?id=2', 
    matches: { 
     title : true, 
     h1 : true, 
     copy : 0 
    } 
    }, 
    { 
    url : '/id=3', 
    matches: { 
     title : false, 
     h1 : false, 
     copy : 6 
    } 
    }, 
    { 
    url : '/id=3', 
    matches: { 
     title : false, 
     h1 : false, 
     copy : 7 
    } 
    } 
]; 

results = results.sort(function(a, b) { 
    return (a.matches.title && !b.matches.title ? -1 
     : (!a.matches.title && b.matches.title ? 1 
     : (a.matches.h1 && !b.matches.h1 ? -1 
     : (!a.matches.h1 && b.matches.h1 ? 1 
     : b.matches.copy - a.matches.copy)))); 
}); 
+1

Я бы добавил некоторые скобки в оператор return. Предшествие вложенных троичных операторов различается на разных языках и ИМО, лучше не заботиться о том, как это происходит на текущем языке, но всегда использует паренс. – ThiefMaster

+0

@ThiefMaster: Мне действительно нравится, как JavaScript позволяет иметь вложенные условные операторы, начиная каждый новый случай с ':' на новой строке. Но parens действительно проясняют ситуацию. – pimvdb

+0

Это похоже на то, что мне нужно ... однако, если я изменяю значения в первом объекте, так что у него есть заголовок: false, h1: false и copy: 2, он по-прежнему отображается как первый элемент в отсортированном результате задавать. Любая идея почему? – Steve

1

Это легко возможно, вызвав results.sort(function(a, b) { ... });, а затем добавив правильную логику для обратного вызова: Return -1, если < b, 1, если > b, 0, если a == b.

Объекты в JavaScript не заказываются. Вы должны преобразовать его в массив, если вы хотите, определенный порядок:

var resultList = []; 
for(var elem in results) { 
    resultList.push(results[elem]); 
} 
resultList.sort(function(a, b) { 
    // perform your sorting 
}); 

Поскольку объекты передаются по ссылке, вы можете использовать results[..] для доступа к одному из объектов.

+0

'sort()' работает на массивах, но у него есть объект. – PiTheNumber

+0

oops.не заметил этого. – ThiefMaster

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