Javascript 复数数组排序

Javascript 复数数组排序,javascript,jquery,arrays,Javascript,Jquery,Arrays,假设我有以下数组: var articles = [ { id: 7989546, tags: [ "98#6", "107#6", "558234#7" ] }, //... ] 此数组的每个元素(部分)表示我们网站中的某种内容。它有一个id,并标有人物(#6)和/或主题(#7) 将向用户提供一个包含建议或推荐标记的co

假设我有以下数组:

var articles = [
     {
          id: 7989546,
          tags: [
              "98#6",
              "107#6",
              "558234#7"
          ]
     },
     //...
]
此数组的每个元素(部分)表示我们网站中的某种内容。它有一个id,并标有人物(#6)和/或主题(#7)

将向用户提供一个包含建议或推荐标记的cookie,如下所示:

var suggestions = [
     "46#6",
     "107#6",
     "48793#7"
]
考虑这些标签,比如将向最终用户显示的建议,比如“也许你对阅读感兴趣…”

建议
数组已按标记优先级排序。这意味着,第一个标签比第二个标签与用户更相关

现在,我想做的是以相同的方式排列我的
文章
数组,即按标记优先级

不应应用任何筛选器,因为
文章
数组保证包含至少具有
建议
数组中一个标记的元素

如果我有一篇带标签的文章:
[“98#6”,“107#6”,“558234#7”]
和另一篇带标签的文章:
[“46#6”,“36987#7”
,我希望后者是第一位的,因为标签
46#6
107#6
数组中的

如何实现这种排序(使用两个数组)

注意:jQuery解决方案很乐意接受。

只需创建自己的排序函数,然后使用
.indexOf
检查标记是否存在。您必须自行决定处理的问题是冲突最有意义的问题。如果一篇文章使用优先级为1的标记进行标记,而另一篇文章使用3个优先级较低的标记进行标记,谁获得优先级?T这里涉及到一些逻辑,在我建议的解决方案中,我只是通过使用建议的长度和优先级的总和来计算总优先级。如果您愿意,这可以进行调整以提供不同类型的碰撞检测,但方法基本相同

步骤1:创建比较函数

这将根据tagCount的结果对数组进行降序排序。也就是说,如果tagCount返回的右值为6,左值为3,则先对6进行排序

var compareFn = function(left,right){
    return tagCount(right.tags) - tagCount(left.tags);
};
步骤2:创建用于确定优先级的标记计数“算法”

这只会优先于最早出现的匹配,但也会为多个随后出现的匹配赋予一些权重。它通过从匹配数组的长度中减去匹配的索引来实现(建议)。因此,如果有5个建议,并且第一个建议匹配,那么最终的值为5(长度=5-索引=0)

var tagCount=函数(标记){
var计数=0;
对于(var i=0;i-1)
计数+=标签长度-重量;
}
返回计数;
}

堆栈片段

var文章=[
{
id:7989546,
标签:[
"107#6",
"558234#7"
]
},
{
id:756,
标签:[
"98#6",
"558234#7"
]
},
{
id:79876,
标签:[
"98#6",
"107#6",
"558234#7"
]
},
{
id:7984576,
标签:[
"98#6",
"107#6",
"46#6"
]
}
];
风险值建议=[
"46#6",
"107#6",
"48793#7"
];
var compareFn=函数(左、右){
返回tagCount(right.tags)-tagCount(left.tags);
};
var tagCount=函数(标记){
var计数=0;
对于(var i=0;i-1)
计数+=标签长度-重量;
}
返回计数;
}
var a=articles.sort(compareFn);
控制台日志(a);
document.querySelector(“#d”).innerHTML=JSON.stringify(a);

我的方法:按相关性得分之和排序

给你:

var articles = [
     {
          id: 7989546,
          tags: [
              "98#6",
              "107#6",
              "558234#7"
          ]
     },
     {
          id: 8000000,
          tags: [
              "107#6",
              "107#10",
              "558234#7",
              "5555#1"
          ]
     },
     {
          id: 8333000,
          tags: [
              "46#6",
              "107#6",
              "666234#7",
              "107#6"
          ]
     }

];


var suggestions = [
     "46#6",
     "107#6",
     "48793#7"
];
您希望按标签对文章进行排序,而标签等级是在建议中定义的。一种简单的方法是:

步骤1)对于每篇文章,获取
建议中存在的每个标签的索引。如果不存在,则放弃

给出的建议[“a”、“b”、“c”]

物品标签[“a”、“b”、“zzzz”、“yyyy”]

将映射到索引[0,1](最后两个标记被丢弃,因为它们不在建议列表中)

步骤2)计算关联度。排名越高的标记(索引越小)产生的值越大(请参见下面的函数
degreeofrerelevance()

步骤3)求和总关联度并按此值排序。因此,包含排名较高标签(基于建议)的文章将获得较高的总分

快速示例:

带标签的物品:[a、b、c]

带标签的物品:[b,c]

带标签的物品:[c、d、e、f]

给出建议:[a、b、c]

文章将映射到分数:

文章索引:[0,1]=>总分:3+2=5

文章索引:[1]=>总分:2

文章索引:[2]=>总分:1

因此,按分数排序时,文章被列为最相关的文档

以下是该方法的工作代码:

function suggest(articles, suggestions){
    function degreeOfRelavance(t){
        return suggestions.length - suggestions.indexOf(t); 
    }
    function weight(tags){
        return (tags.map(degreeOfRelavance)).reduce(function(a,b){
          return a+b
        },0);
    }
    function relatedTags(a){
        return a.tags.filter(function(t){
            return suggestions.indexOf(t)>=0
        });
    }
    
    articles.sort(function(a,b){
        return weight(relatedTags(a)) < weight(relatedTags(b))
    });
    return articles;
}

// See the output
console.log(suggest(articles,suggestions));
    
功能建议(文章、建议){
功能度频率(t){
return suggestions.length-suggestions.indexOf(t);
}
功能重量(标签){
返回(tags.map(degreeOfRelavance)).reduce(函数(a,b){
返回a+b
},0);
}
函数相关标签(a){
返回a.tags.filter(函数(t){
ret
function suggest(articles, suggestions){
    function degreeOfRelavance(t){
        return suggestions.length - suggestions.indexOf(t); 
    }
    function weight(tags){
        return (tags.map(degreeOfRelavance)).reduce(function(a,b){
          return a+b
        },0);
    }
    function relatedTags(a){
        return a.tags.filter(function(t){
            return suggestions.indexOf(t)>=0
        });
    }
    
    articles.sort(function(a,b){
        return weight(relatedTags(a)) < weight(relatedTags(b))
    });
    return articles;
}

// See the output
console.log(suggest(articles,suggestions));