js 数组合并问题

业务描述,在日历上显示一个月跑步的日期
日历这快完全是用前端js实现的,所以只需要后台给一个跑步日期的数组插进日历的数组里就行了,我的思路是做两层循环,但是这样计算量很大,有没有更好的方法?

后台返回一个月中跑步的日期

[1,4,6,8,21]

前端某月 日历数组

[{day:1},{day:2}......{day:31}]

希望合并的最后的结果是

[{day:1,isrun:false},{day:2,isrun:false}...{day:4,isrun:true}...{day:6,isrun:true}....{day:31,isrun:false}]
阅读 7.2k
14 个回答

首先,反对推荐答案,indexOf只是语法糖,内部还是循环

如果这样做,我想了很久,没有想到什么好办法,
但是上面的答案也绝对不对,你想下map、indexOf、include这些方法内部原理是不是还是循环?
只是被封装的很好,使你的代码看起来很优雅。

那么,我们换个思路

let days = [2, 4, 5, 7];
let run = [{ day: 1 }, { day: 2 }......{ day: 31 }];
for(let i=0;i<days.length;i++){
  run[days[i]-1].isrun=true;
}

run数组里的下标是可以利用起来的,实际天数-1就是下标

写之前没注意看 我赞同 @yszou 的答案,只有这样才能实现单层循环,其他的全是语法糖包装,实质运算量并没有减少

var a = [1,4,6,8,21];
var b = [{day:1},{day:2}......{day:31}];

确保 b 是事个“完整”的列表,这个前提下, a 的成员的值,就是 b 的成员的索引值。

即:

$.map(a, function(v){ b[v-1].isrun = true });
// 两层循环?一层即可呀。
let dayArr = [1,4,6,8];
let arr = [{day:1},{day:2},{day:3}];
let result = arr.map((item) => {
    if(dayArr.indexOf(item.day) > -1){
        item.isrun = true;
    }else{
        item.isrun = false;
    }
    // 当前这块可以用ES7的includes简化
    // item.isrun = dayArr.includes(item.day);
    // 或者
    // item.isrun = dayArr.indexOf(item.day) > -1;
    return item;
})
console.log(result); // [{day: 1, isrun: true},{day: 2, isrun: false},{day: 3, isrun: false}]
var arr = [1,4,6,8,21];
var day = 31;
var newArr = [];
for(var i = 1;i <= day;i++){
    var obj = {
        day:i,
        isrun:false
    };
    if(arr.indexOf(i) > -1){
        obj.isrun = true;
    }
    newArr.push(obj)
}
<script>
    var day = [1,4,7];
    var data = [
        {day:1},
        {day:2},
        {day:3},
        {day:4},
        {day:5},
        {day:6},
        {day:7},
        {day:8}
    ]
    
    var newArr = [];
    
    for(var a=0;a<data.length;a++) {
        newArr.push({
            day: data[a].day,
            isrun: day.indexOf(data[a].day) != -1 ? true : false
        });
    }
    
    console.log(newArr);
</script>

有这么复杂

var day = [1,4,6,8,21];
  var run  = [{day:1},{day:2},{day:3},{day:4}];
 console.log(run.map(item =>(day.indexOf(item.day)>=0?item.isrun=true:item.isrun=false,item))) ;

这么点数据量,不要考虑性能问题。可读性更重要。

const days = [1,4,6,8,21]
const result = [...Array(31)].map((u, i) => ({day: i + 1, run: days.includes(i + 1)}))
var runDay = [1,4,6,8,21];
var cand = [{day:1},{day:2}......{day:31}];
var result = cand.map(item => {
    item.isRun = runDay.includes(item.day);
    return item;
})
新手上路,请多包涵

var run = [1,4,6,8,21];
var day = [{day:1},{day:2},{day:3},{day:4}];
var res = day.map(item => {

item && item.day && item.isrun = run.indexOf(item.day) > -1;
return item;

})
console.log(res)

let dayArr = [1,4,6,8,21]
let result = Array(30).fill(0).map((v,i) => { num:i+1, isrun:false })
dayArr.forEach((v) => result[v-1].isrun = true)
let dayList = [1,4,6,8,21];
let calendarList = [{day:1},{day:2},{day:3},{day:4},{day:8},{day:21}];
//不改变calendarList的情况下返回一个新数组
let newList = calendarList.map((item) => {
        return {
         day:item.day,
         run:dayList.indexOf(item.day) > -1
        }
    });
let m = {}
let dayArr = [1,4,6,8,21].map(i => {m[i] = 1})
let result = Array(31).fill(1).map((a, i) => ({day: i+1, run: !!m[i+1]}))
console.log(result)

clipboard.png

同步运行。但尽量减少变量新增和数组遍历。可能会快一点吧。

var runDay = [1,4,6,8,21];
var cand = [{day:1},{day:2}......{day:31}];
var i = 0, len = runDay.length;
for (;i<len;i++) {
    cand[runDay[i] - 1].run = true;
}
i = 0;
len = cand.length;
for (;i<len;i++) {
    //对下面这两种不太了解哪种效率速度更快
    //case1
    cand[i].run = !!cand[i].run;
    //case2
    if (!cand[i].run) {
        cand[i].run = false;
    }
}

赞同 @阡陌夕殇 的答案。

在此,想额外补充一点的是,这个问题实质上是关于时间复杂度的问题,问题中时间复杂度为O(n^2),那应该如何去降低这个时间复杂度?

另外,还有空间复杂度的问题。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题