一、另类排序

题目:

/**
* 1. 排序后输出 id
* @param {Array<Object>} list
* @returns {Array<number>}
* @example
* [
* { id: 2, before: 1 },
* { id: 1, last: true },
* { id: 3, after: 1 },
* { id: 5, first: true },
* { id: 6, last: true },
* { id: 7, last: true },
* { id: 8, last: true },
* ];
* 输出为
* [5, 2, 1, 3, 6, 7, 8];
* [
* { id: 2, before: 3 },
* { id: 1, before: 2 },
* { id: 3, before: 5 },
* { id: 5, before: 6 },
* { id: 6, last: true },
* { id: 7, last: true },
* { id: 8, last: true },
* ];
* 输出:
* [1,2,3,5,6,7,8]
*/

解法1:

 function sort(source, target = []) {
if (source.length === 0) {
return target
}
const current = source.shift()

const { id, before, after, first, last } = current

if (first) {
target.unshift(id)
}

if (last) {
target.push(id)
}

/**
* 前后关系处理,找到对应的index,如果对应的目标未入盏则放到最后进行处理
*/
if ('before' in current || 'after' in current) {
const targetId = before || after
const index = target.findIndex(value => value === targetId)
if (index === -1) {

/**
* source 和 target都不存在目标id的情况下,直接插入
*/
if (source.find(value => value === targetId)) {
source.push(current)
return sort(source, target)
} else {
target.push(id)
}

} else {
target.splice('before' in current ? index : index + 1, 0, id)
}
}

return sort(source, target)
}

解法2:

function parse(list) {
let result = [];
let filtered = [];
for(let i of list){
if(i.first){
result.unshift(i.id);
}else if(i.last){
result.push(i.id);
}else{
filtered.push(i);
}
}

while(filtered.length){
let cur = filtered.shift();
let key = cur.before ? cur.before : cur.after;
let index = result.findIndex(i=>i===key);
if(index !== -1){
result.splice(cur.before ? index: index+1,0,cur.id);
}else{
filtered.push(cur);
}

}
}

二、二维数组转树状结构

题目:

/**
* 2. 将数组转换成树状结构
* @param {Array} arr
* @returns {Object}
* @example
* [
* { id: 1, name: 'i1' },
* { id: 2, name: 'i2', parentId: 1 },
* { id: 4, name: 'i4', parentId: 3 },
* { id: 3, name: 'i3', parentId: 2 },
* { id: 8, name: 'i8', parentId: 7 },
* ]
* 转换后
* {
* id: 1,
* name: 'i1',
* children: [
* { id: 2, name: 'i2', parentId: 1, children: [...] },
* ]
* }
*/

解答:

function convert2Tree(arr) {
let parentMap = {};
let root;
arr.sort((a,b)=>a.id-b.id);

for(let node of arr){
node.children = [];
if(!node.parentId){

root = node;

}else{
let parent = parentMap[node.parentId];
if(parent){
parent.children.push(node);
}

}
parentMap[node.id] = node;
}
return root;
}

三、用setTimeout实现setInterval

/**
* 3. 实现 setInterval
* 利用 setTimeout 实现 setInterval
* 利用 clearTimeout 实现 clearInterval
*/

/**
* @param {Function} callback
* @param {number} duration
* @returns {number}
* @example
* mySetInterval(()=> {
* console.log('xxx');
* }, 200);
*/
let timerMap = {};
let id = 0;
function mySetInterval(callback, duration) {
let timerId = id;
id++;
function fn(){
callback();
timerMap[timerId] = setTimeout(()=>{
fn();
}, duration)
}
timerMap[timerId] = setTimeout(fn, duration);
return timerMap[timerId];
}

/**
* @param {number} timer
* @returns {void}
* @example
* const timer = mySetInterval(()=> {
* console.log('xxx');
* }, 200);
* setTimeout(() => {
* myClearInterval(timer);
* }, 1000);
*/
function myClearInterval(timer) {
clearTimeout(timerMap[timer]);
// clearTimeout(timer);
delete timerMap[timer];

}

参考