最近遇到了一個演算法題,要求對一個key:value這樣的數組,根據value值對key進行排序(這裡的value值可以指多行),一個酒店的評分系統的邏輯。
名稱衛生用戶體驗安全性
A x1 y1 z1
B x2 y2 z2
... ... ... ...
類似於上面的這樣子的,然後先對衛生排序,衛生排完,選出衛生排序得出的前三名,選擇前面選出的前三民,根據用戶體驗排序,選出用戶體驗前兩名,根據安全性排序,選出安全性的第一名。
最後輸出這個第一名。
感覺其實都差不多,但資料也查過,map函數也看了,但還是理解不了到底該怎麼搞,求大佬賜教一波。 (ps:明明感覺自己演算法不算差啊,可是每次遇到稍微複雜一點的演算法就被搞暈了,剛入前端坑不久,基本的js相關的程式碼都擼過一遍),求大佬解惑。
高洛峰2017-05-19 10:45:49
首先你這個是題目還是專案? 如果是真實項目,你可以用上 lodash
的 sortBy
對清單中的物件進行排序。
假設你的飯店清單模型簡化為:
const list = [
{ name: 'foo', a: 3, b: 5, c: 7 }, // 这个是酒店模型,a, b, c就是各个因素的打分
...
]
現在需求是把list中的物件先按a排序,再按b排序,再按c排序。 實現起來就是:
let result = _.sortBy(list, o = > o.a); // 先按a排序
result = _.sortBy(list, o => o.b); // 再按b排序
result = _.sortBy(list, o => o.c); // 最后按C排序
如果分數越大越好,那麼應該是逆序
let result = _.sortBy(list, o = > -o.a); // 先按a逆序排序
result = _.sortBy(list, o => -o.b); // 再按b逆序排序
result = _.sortBy(list, o => -o.c); // 再按c逆序排序
像題中所說的,要取出3,2, 1名,那麼不需要每次都對全部結果排。
let result = _.sortBy(list, o = > -o.a).slice(3); // 排好序取三个
result = _.sortBy(list, o => -o.b).slice(2);
result = _.sortBy(list, o => -o.c).slice(1);
result[0] // 第一名
如果是面試題,還要完成sortBy
这个函数, 可以简单利用Array#sort
實作:
function sortBy(list, iterator) {
return list.slice(0).sort(function(left, right) {
left = iterator(left);
right = iterator(right);
return left < right ? -1 : 1;
});
}
要注意的是:sortBy
要实现成稳定排序, 即两个分数一致的对象,排序前后相对位置要保持不变。
当然直接使用上Array#sort(func)
這個函數也是很方便的。