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));