先来一道面试题热热身.
题目要求
找出一个页面中出现次数最多的标签!!!
个人解法:
var eles = document.getElementsByTagName('*');
var rs = [];
for(var i=0; i<eles.length; i++) {
var tag_name = eles[i].tagName.toLowerCase();
if(undefined != tag_name) {
if(inJsonArray(rs, tag_name)) {
addWeight(rs, tag_name);
}else {
rs.push({
tag : tag_name,
weight : 1
})
}
}
}
SortByWeight(rs);
思路:
拿到所有的标签 -- 根据标签名称聚类 --- 根据权重排序.
如果有更好的方法,欢迎交流.下面看今天这个问题:
获取一张图片的 top N 主色值, 和上面最多标签的问题很类似,数据大小有区别,别的都差不多的.
这个问题思路很清晰,第一步,拿到图片的数据;第二步,根据色值进行聚类;第三步,对聚类结果排序.所以这次就是根据这个思路去实现.
1,数据获取
图片数据获取使用了 canvas 的 getImageData() 方法,能获取到图片每个像素点的 rgba 数据.
var imgdatas=context.getImageData(0,0,150,150);//获取当前canvas数据
var imgdata = imgdatas.data;//获取rgba数据
var i = 0, len = imgdata.length;
var arr = [];
//将图片rgba数据push到新数组中
for(i ; i<len ; i+=4 ) {
arr.push(imgdata[i]+','+imgdata[i+1]+','+imgdata[i+2]+','+imgdata[i+3]);
}
这样就可以拿到图片的所有数据了,剩下的就是数学问题了.
2,数据聚类
去重, 相同色值合并,记录该色值出现个数(权重)weight
聚类方法就比较多了,直接数学统计,或者 k-means, 决策树,朴素贝叶斯,支持向量机等等,喜欢哪个就用哪个就可以了,但是还是需要考虑下不同方法的适用情况和效率什么的了.我们会得到这样一个数组
[{rgba: '21,12,45,0', weight: 12}, {...}]
来记录色值和出现次数,
3,聚类结果排序
对上一步中得到的 json 数组进行排序,根据属性 weight 的值从大到小或者从小到大排序,排序算法就不用多言了.
4,结果预览5,to Do
相似色值合并
rgba(234,234,234,1) 和 rgba(234,235,235,1) 类似的这种是否有必要合并成为一个值,这里又会涉及到相似度计算等问题.
优化聚类算法
降低复杂度,提升性能,提升执行速度
结合可视化的一些东西
6,总结
数据多的处理还是放在后端比较合适,毕竟可以利用分布式框架等多端计算.
而浏览器处理数据的能力还是有限.
来源: https://juejin.im/entry/5a659e626fb9a01cba42b297