Расширенная сортировка объектов - PullRequest
1 голос
/ 22 февраля 2012

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

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, являющийся истинным, несет наибольший вес (самый верхний), за которым следует число вхождений в копии страницы (match.copy).

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

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

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


РЕДАКТИРОВАТЬ: Преобразованный набор результатов в массив объектов. Новая структура:

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, который кажется многообещающим, но у меня нет опыта его использования. Не уверен, что это верное направление или нет.

Ответы [ 2 ]

5 голосов
/ 22 февраля 2012

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

Вы можете использовать .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 голос
/ 22 февраля 2012

Это легко сделать, вызвав results.sort(function(a, 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[..] для доступа к одному из объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...