【问题标题】:Sorting list by most matched listitems按最匹配的列表项排序列表
【发布时间】:2016-11-26 02:07:22
【问题描述】:

我有一个数组,其中包含最少 3 个最多 5 个 的对象数组。我的目标是将这些对象附加到列表中,因此我的结果将包含 3、4 或 5 个列表。我正在尝试以某种非常规的方式对这些列表进行排序。我想将列表项与列表项在其他列表中的位置进行匹配。然后我想将匹配最多的列表项放在顶部,将匹配最少的项放在底部列表始终包含 10 个列表项。

因此,例如,如果“项目 3”出现在所有五个列表中,则“项目 3”将移动到所有列表的列表中的位置 1。如果“项目 21”出现在三个列表中,并且没有其他列表项目出现在三个以上的列表中,则“项目 21”将移动到所有包含“项目 21”的列表中的位置 2,并且以此类推。

所有列表项都是可以通过id 匹配的对象。我的数组可能如下所示:

var listsToSort = [
  [
      {id: 1, name: 'Item 1'},
      {id: 3, name: 'Item 3'},
      {id: 7, name: 'Item 7'},
      {id: 8, name: 'Item 8'},
      {id: 9, name: 'Item 9'},
      {id: 11, name: 'Item 11'},
      {id: 12, name: 'Item 12'},
      {id: 16, name: 'Item 16'},
      {id: 18, name: 'Item 18'},
      {id: 19, name: 'Item 19'}
  ],
  [
      {id: 2, name: 'Item 2'},
      {id: 3, name: 'Item 3'},
      {id: 5, name: 'Item 5'},
      {id: 12, name: 'Item 12'},
      {id: 14, name: 'Item 14'},
      {id: 15, name: 'Item 15'},
      {id: 16, name: 'Item 16'},
      {id: 18, name: 'Item 18'},
      {id: 21, name: 'Item 21'},
      {id: 23, name: 'Item 23'}
  ],
  [
      {id: 3, name: 'Item 3'},
      {id: 4, name: 'Item 4'},
      {id: 5, name: 'Item 5'},
      {id: 6, name: 'Item 6'},
      {id: 9, name: 'Item 9'},
      {id: 15, name: 'Item 15'},
      {id: 18, name: 'Item 18'},
      {id: 20, name: 'Item 20'},
      {id: 21, name: 'Item 21'},
      {id: 22, name: 'Item 22'}
  ],
  [
      {id: 3, name: 'Item 3'},
      {id: 9, name: 'Item 9'},
      {id: 10, name: 'Item 10'},
      {id: 16, name: 'Item 16'},
      {id: 18, name: 'Item 18'},
      {id: 22, name: 'Item 22'},
      {id: 23, name: 'Item 23'},
      {id: 24, name: 'Item 24'},
      {id: 26, name: 'Item 26'},
      {id: 28, name: 'Item 28'}
  ],
  [
      {id: 3, name: 'Item 3'},
      {id: 9, name: 'Item 9'},
      {id: 11, name: 'Item 11'},
      {id: 13, name: 'Item 13'},
      {id: 15, name: 'Item 15'},
      {id: 16, name: 'Item 16'},
      {id: 18, name: 'Item 18'},
      {id: 25, name: 'Item 25'},
      {id: 27, name: 'Item 27'},
      {id: 29, name: 'Item 29'}
  ]
 ];

此示例数组的结果在排序后将如下所示:

匹配的项目会收到一个突出显示类。列表中没有匹配项的“空白”被其他列表中不存在的剩余列表项填充。

为了澄清,匹配的项目被放置在所有列表中的某些列表位置。

在这件事上我将如何对数组进行排序?

FIDDLE

【问题讨论】:

  • 如何决定相同计数的顺序?它看起来像随机排序。
  • @NinaScholz 该顺序是大多数匹配项。第一项有 5 个匹配项,第二项也是如此,第三项有 4 个匹配项,第四项有 4 个匹配项,第五项有 3 个匹配项,依此类推。
  • 我有一个问题,为什么是16而不是9?两者的计数均为 4。-
  • @NinaScholz 如果计数相同,则顺序无关紧要。第一击就好了。这些名称当前是占位符名称。 “Item 16”也可以是名称“Lorum”,“Item 9”可以是名称“Ipsum”。很抱歉,如果这引起了混乱。

标签: javascript jquery arrays list sorting


【解决方案1】:

此建议使用排序对象和对每个单个对象的引用,以供以后引用以填充数组。这是通过使用排序后的引用来完成的,然后它插入一个对象,如果,或者null,如果不是。

为了保持正确的顺序,未填充的空白将用索引 10 或更大的对象填充。当索引 10 以上的所有间隙都被填满时,数组的长度设置为 10 并返回。

raw array before moving values                                      moving values

    0       1       2       3       4                                   4 
------  ------  ------  ------  ------                              ------
    3       3       3       3       3 fixed part with values            3 
   18      18      18      18      18                                  18
    9    null       9       9       9                                   9
   16      16    null      16      16                                  16
 null      15      15    null      15                                  15
 null       5       5    null    null                                null <--
   11    null    null    null      11                                  11   |
   12      12    null    null    null                                null <----
 null      21      21    null    null                                null <------
 null    null      22      22    null                                null <--------
 ------------------------------------                               -----   | | | |
 null      23    null      23    null variable part to fill above    null   | | | |
    1    null    null    null    null                                null   | | | |
 null       2    null    null    null                                null   | | | |
 null    null       4    null    null                                null   | | | |
 null    null       6    null    null                                null   | | | |
    7    null    null    null    null                                null   | | | |
    8    null    null    null    null                                null   | | | |
 null    null    null      10    null                                null   | | | |
 null    null    null    null      13                                  13 --- | | |
 null      14    null    null    null                                null     | | |
   19    null    null    null    null                                null     | | |
 null    null      20    null    null                                null     | | |
 null    null    null      24    null                                null     | | |
 null    null    null    null      25                                  25 ----- | |
 null    null    null      26    null                                null       | |
 null    null    null    null      27                                  27-------- |
 null    null    null      28    null                                null         |
 null    null    null    null      29                                  29 ---------

此解决方案无法提供稳定的结果,因为对于具有相同计数的对象,排序顺序不稳定。

var listsToSort = [[{ id: 1, name: 'Item 1' }, { id: 3, name: 'Item 3' }, { id: 7, name: 'Item 7' }, { id: 8, name: 'Item 8' }, { id: 9, name: 'Item 9' }, { id: 11, name: 'Item 11' }, { id: 12, name: 'Item 12' }, { id: 16, name: 'Item 16' }, { id: 18, name: 'Item 18' }, { id: 19, name: 'Item 19' }], [{ id: 2, name: 'Item 2' }, { id: 3, name: 'Item 3' }, { id: 5, name: 'Item 5' }, { id: 12, name: 'Item 12' }, { id: 14, name: 'Item 14' }, { id: 15, name: 'Item 15' }, { id: 16, name: 'Item 16' }, { id: 18, name: 'Item 18' }, { id: 21, name: 'Item 21' }, { id: 23, name: 'Item 23' }], [{ id: 3, name: 'Item 3' }, { id: 4, name: 'Item 4' }, { id: 5, name: 'Item 5' }, { id: 6, name: 'Item 6' }, { id: 9, name: 'Item 9' }, { id: 15, name: 'Item 15' }, { id: 18, name: 'Item 18' }, { id: 20, name: 'Item 20' }, { id: 21, name: 'Item 21' }, { id: 22, name: 'Item 22' }], [{ id: 3, name: 'Item 3' }, { id: 9, name: 'Item 9' }, { id: 10, name: 'Item 10' }, { id: 16, name: 'Item 16' }, { id: 18, name: 'Item 18' }, { id: 22, name: 'Item 22' }, { id: 23, name: 'Item 23' }, { id: 24, name: 'Item 24' }, { id: 26, name: 'Item 26' }, { id: 28, name: 'Item 28' }], [{ id: 3, name: 'Item 3' }, { id: 9, name: 'Item 9' }, { id: 11, name: 'Item 11' }, { id: 13, name: 'Item 13' }, { id: 15, name: 'Item 15' }, { id: 16, name: 'Item 16' }, { id: 18, name: 'Item 18' }, { id: 25, name: 'Item 25' }, { id: 27, name: 'Item 27' }, { id: 29, name: 'Item 29' }]],
    count = Object.create(null),
    countKeys,
    newList, 
    reference;

reference = listsToSort.map(function (a) {
    var o = Object.create(null);
    a.forEach(function (b) {
        count[b.id] = (count[b.id] || 0) + 1;
        o[b.id] = b;
    });
    return o;
});
countKeys = Object.keys(count);
countKeys.sort(function (a, b) { return count[b] - count[a]; });
newList = reference.map(function (a) {
    var temp = countKeys.map(function (k) {
            return a[k] || null;
        }),
        i = 0, j = 10;

    while (i < 10) {
        if (!temp[i]) {
            while (!temp[j]) {
                j++;
            }
            temp[i] = temp[j];
            j++;
        }
        i++;
    }
    temp.length = 10;
    return temp;
});

console.log(newList);

【讨论】:

  • 仅排序是不够的,我想将列表项放在与其他列表相同的位置。所以“差距”必须用其他列表中不匹配的列表项来填充。通过使用您的方法,第二个列表中的“第 16 项”将放置在位置 3,而第二个列表中的位置 3 将是“间隙”,因此将填充不匹配的列表项。并且“第 16 项”应放置在与其他列表中的“第 16 项”相同的高度
  • 我无法理解您的最后一段:“此解决方案无法提供稳定的结果,因为具有相同计数的对象的排序顺序不稳定。”这会在什么用例中中断?
  • 简单来说,对于其他排序算法不同的系统,结果会有所不同,但仍然保持相同的位置。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多