jirengu / frontend-interview

前端笔试面试题题库
1.29k stars 139 forks source link

JS面试题求解 #21

Open willes opened 7 years ago

willes commented 7 years ago

一、从某数据库接口得到如下值:

{
 rows: [
  ["Lisa", 16, "Female", "2000-12-01"],
  ["Bob", 22, "Male", "1996-01-21"]
 ],
 metaData: [
  {name: "name", note: ''},
  {name: "age", note: ''},
  {name: "gender", note: ''},
  {name: "birthday", note: ''}
 ]
}

rows是数据,metaData是对数据的说明。现写一个函数,将上面的Object转化为期望的数组:

[
 {name: "Lisa", age: 16, gender: "Female", birthday: "2000-12-01"},
 {name: "Bob", age: 22, gender: "Male", birthday: "1996-01-21"},
]

二、写一个函数,判断给定的日期是几月的第几周,当月1日属于上一月的,该周计入上一月。例如: 1)输入日期2016-02-01,返回结果为2-1,表示2016年2月1日属于2月的第一周; 2)输入日期2016-09-01,返回结果为8-5,表示2016年9月1日属于8月的第五周。

三、数组

a = [
{id: 10001, name: "Lisa", age: 16},
{id: 10002, name: "Bob", age: 22},
{id: 10003, name: "Alice", age: 20},
];

数组

b = [
{id: 10001, gender: "Female"},
{id: 10002, name: "Bob King", birthday: "1996-01-22"},
{id: 10005, name: "Tom", birthday: "2000-01-01"},
];

写一个函数按id用b更新a,期望得到的结果为:

[
{id: 10001, name: "Lisa", age: 16, gender: "Female"},
{id: 10002, name: "Bob King", birthday: "1996-01-22", age: 22},
{id: 10003, name: "Alice", age: 20},
{id: 10005, name: "Tom", birthday: "2000-01-01"},
]
zhangolve commented 7 years ago

第一题做了一下,时间复杂度o3

let  a={
rows: [
["Lisa", 16, "Female", "2000-12-01"],
["Bob", 22, "Male", "1996-01-21"]
],
metaData: [
{name: "name", note: ''},
{name: "age", note: ''},
{name: "gender", note: ''},
{name: "birthday", note: ''}
]
};
let rows=a.rows;
let metaData=a.metaData;
let props=[];
let result=[];
for(let i=0;i<metaData.length;i++)
  {
    props.push(metaData[i].name)
  }
for(let j=0;j<rows.length;j++)
  {
   let  ob=new Object 
    for(let k=0;k<props.length;k++)
      { 
        var name=props[k];
        ob[name]=rows[j][k];
      }
    result.push(ob);
  }
console.log(result);  

在Chrome 控制台测试可行

FrankFang commented 7 years ago

代码外面加上三个 ` 可以变好看 @zhangolve @willes 我帮你俩都加上了

RookieDay commented 7 years ago

简单实现,先做第一道题目,下面是我的解法:

        var data = {
            rows: [
                ["Lisa", 16, "Female", "2000-12-01"],
                ["Bob", 22, "Male", "1996-01-21"]
            ],
            metaData: [{
                name: "name",
                note: ''
            }, {
                name: "age",
                note: ''
            }, {
                name: "gender",
                note: ''
            }, {
                name: "birthday",
                note: ''
            }]
        }

        var result = data.rows.reduce(function(prev1, cur1) {
            prev1.push(data.metaData.reduce(function(prev, cur, index) {
                prev[cur.name] = cur1[index];
                return prev;
            }, {}))
            return prev1;
        }, []);

        console.log(result);
        console.log(result[0]);
        console.log(result[1]);
测试结果:
[Object, Object]
Object {name: "Lisa", age: 16, gender: "Female", birthday: "2000-12-01"}
Object {name: "Bob", age: 22, gender: "Male", birthday: "1996-01-21"}
fonglezen commented 7 years ago

第一题:

`

function formatData(rows,names){
        var newData = [];
        for(var i = 0,rl = rows.length; i < rl; i++){
            var newObj = {};
            for(var j = 0,nl = names.length; j < nl; j++){
                newObj[names[j].name] = rows[i][j];
            }
            newData.push(newObj);
        }

        return newData;
    }

`

willes commented 7 years ago

@fonglezen @RookieDay 请问第三题怎么弄呢

henryzp commented 7 years ago

话说第二题,我愣是看不懂。。

你2016年9月1号,在8月份的日历里面也是算第五周啊??那为什么2月1号算2月的第一周,9月1号算8月的第五周?

这个逻辑判断是啥??

henryzp commented 7 years ago

@willes ,简单的

遍历b数组,拿它单个对象里面的id去找a里面的对象,然后for in添加,相同的属性continue

zhangolve commented 7 years ago

@henryzp 第二题要是能够用库的话,只是获取当年的第几周其实就简单了。然而并不是,总觉得第二题真要是面试出的话很坑,并不像是考js,而是考算法,当然算法是基础。

moment('2016-12-30', 'YYYY-MM-DD').format('W')
ningt commented 7 years ago

第三题 @willes , 复杂度应该O(N)吧

const map = a.reduce((acc, curr, index) => {
  acc[curr.id] = index;
  return acc;
}, {});

b.forEach(o => {
  const index = map[o.id];

  if (index !== undefined) {
    a[index] = Object.assign(a[index], o);
  }
  else {
    a.push(o);
  }
});
fonglezen commented 7 years ago

@ningt


const map = a.reduce((acc, curr, index) => {
  acc[curr.id] = index;
  return acc;
}, {});

这里是什么意思?干嘛要这样做呢?

ningt commented 7 years ago

@fonglezen 建一个反向查找的表 id -> index,不然对于b数组里面每个id都需要遍历一遍a数组,最后复杂度就变成O(n^2)了。

kevinwulong commented 7 years ago

第一题

var database = {
    rows: [
    ["Lisa", 16, "Female", "2000-12-01"],
    ["Bob", 22, "Male", "1996-01-21"]
    ],
    metaData: [
    {name: "name", note: ''},
    {name: "age", note: ''},
    {name: "gender", note: ''},
    {name: "birthday", note: ''}
    ]
}

function index (data) {
    let rows = data.rows;
    let metaData = data.metaData;
    let narr={};
    for(var j=0; j<rows.length;j++){
        for(var  i = 0; i<metaData.length; i++){
            var arr = [];
            narr[metaData[i].name] = rows[j][i];
            arr.push(narr);

        }
        console.log(arr)
    }

}
450611 commented 7 years ago

第一题

let a = {
    rows: [
        ['Lisa', 16, 'Female', '2000-12-01'],
        ['Bob', 22, 'Male', '1996-01-21']
    ],
    metaData: [
        { name: 'name', note: '' },
        { name: 'age', note: '' },
        { name: 'gender', note: '' },
        { name: 'birthday', note: '' }
    ]
};

let rows = a.rows, metaData = a.metaData, result = [];

for (let i = 0, len = rows.length; i < len; i++) {
    let _stack = result[i] = {};
    for (let k = 0; k < rows[i].length; k++) {
        _stack[ metaData[k].name ] = rows[i][k];
    }
}
console.log(result);
LZ0211 commented 7 years ago
//NO.1
//函数式
function convert(data){
    var metas = data.metaData.map(ele=>ele.name);
    return data.rows.map(ele=>{
        var obj = {};
        metas.forEach((meta,index)=>{
            obj[meta] = ele[index];
        });
        return obj;
    });
}

//NO.3
//函数式
function merge(a,b){
    var logs = {};
    var array = [];
    //copy a;
    a.forEach(ele=>{
        var obj = {};
        Object.keys(ele).forEach(key=>obj[key]=ele[key]);
        logs[ele.id] = array.length;
        array.push(obj);
    });
    //merge b;
    b.forEach(ele=>{
        var obj = {};
        var index = logs[ele.id];
        if (index !== undefined){
            obj = array[index];
        }
        Object.keys(ele).forEach(key=>obj[key]=ele[key]);
        if (index == undefined){
            array.push(obj);
        }
    });
    return array;
}
xinzikang commented 7 years ago

NO.01 var rows = [ ["Lisa", 16, "Female", "2000-12-01"], ["Bob", 22, "Male", "1996-01-21"] ]; var metaData = [ {name: "name", note: ''}, {name: "age", note: ''}, {name: "gender", note: ''}, {name: "birthday", note: ''} ]; var result = []; rows.forEach(function (item, index, arr) { var json = {}; metaData.forEach(function (metaDataItem, metaDataIndex, metaDataArr) { json[metaDataItem.name] = item[metaDataIndex]; }) result.push(json); }) NO.03 a = [ {id: 10001, name: "Lisa", age: 16}, {id: 10002, name: "Bob", age: 22}, {id: 10003, name: "Alice", age: 20}, ];

b = [
    {id: 10001, gender: "Female"},
    {id: 10002, name: "Bob King", birthday: "1996-01-22"},
    {id: 10005, name: "Tom", birthday: "2000-01-01"},
];
b.forEach(function (itemB,indexB,arrB) {
    a.forEach(function (itemA,indexA,arrA) {
        if(itemA.id == itemB.id){
            for(var key in itemB){
                itemA[key] = itemB[key];
            }
        } else{
            var noHave = true;
            for(var i=0;i< a.length;i++){
                if(a[i].id == itemB.id){
                    noHave = false;
                }
            }
                if(noHave){
                    a.push(itemB);
                }
        }
    })
})
hanjinjun commented 7 years ago

第一小题,写的不完美,但是勉强能运行。

var data={
    rows: [
    ["Lisa", 16, "Female", "2000-12-01"],
    ["Bob", 22, "Male", "1996-01-21"]
    ],
     metaData: [
     {name: "name", note: ''},
     {name: "age", note: ''},
     {name: "gender", note: ''},
    {name: "birthday", note: ''}
    ]
    };          
//函数主体部分    
function change(rows,meta){
    var my=[];
    rows.map(function(ele){
        var temp={};
        ele.map(function(e,i){
            temp[meta[i].name]=e;
        });
        my.push(temp);
    });
    console.log(my);
};
change(data.rows,data.metaData);
jumperchuck commented 7 years ago

第一题:

    var data = {
        rows: [
            ["Lisa", 16, "Female", "2000-12-01"],
            ["Bob", 22, "Male", "1996-01-21"]
        ],
        metaData: [
            {name: "name", note: ''},
            {name: "age", note: ''},
            {name: "gender", note: ''},
            {name: "birthday", note: ''}
        ]
    };
    var rows = data.rows;
    var metaData = data.metaData;
    var sbData = {};
    var allData = [];
    for(var i=0; i<rows.length; i++){
        sbData = {};
        for(var j=0; j<metaData.length; j++){
            sbData[metaData[j].name] = rows[i][j];
        }
        allData.push(sbData);
    }
    console.log(allData);

第二题不会... 第三题:

var a = [
    {id: 10001, name: "Lisa", age: 16},
    {id: 10002, name: "Bob", age: 22},
    {id: 10003, name: "Alice", age: 20},
];
var b = [
    {id: 10001, gender: "Female"},
    {id: 10002, name: "Bob King", birthday: "1996-01-22"},
    {id: 10005, name: "Tom", birthday: "2000-01-01"},
];
b:for(var i=0; i<b.length; i++){
    for(var j=0; j<a.length; j++){
        if(a[j].id == b[i].id){
            for(var key in b[i]){
                a[j][key] = b[i][key];
            }
            continue b;
        }
    }
    a.push(b[i]);
}
console.log(a);

感觉自己写的好蠢

coolHt commented 7 years ago

第一题: var obj={ rows: [ ["Lisa", 16, "Female", "2000-12-01"], ["Bob", 22, "Male", "1996-01-21"] ], metaData: [ {name: "name", note: ''}, {name: "age", note: ''}, {name: "gender", note: ''}, {name: "birthday", note: ''} ] };

var arr=[];
var meta=obj.metaData;
for(var i=0;i<obj.rows.length;i++){
    var o=new Object();
    console.log(o);
    for(var n=0;n<meta.length;n++){
        console.log(meta[n].name);
        var na=meta[n].name;
        o[na]=obj.rows[i][n];
    }
    arr.push(o);
}
console.log(arr);

应该没有错吧。。。不知道写的规范不规范。。

tangxiaolang101 commented 7 years ago

@ningt 这种问题一般是不是不会去考虑兼容性,如果考虑兼容性,设计时间复杂度是不是就上去了?

ningt commented 7 years ago

@tangxiaolang101 个人感觉这种题应该跟兼容性没太大关系,假如面试官说你不可以用 reduce,你用 for也是一样的。

tangxiaolang101 commented 7 years ago

@ningt 哦哦,也对。那对象拷贝这个问题,如果是兼容性的化,时间复杂度是不是就只能是O(n^2)了

ningt commented 7 years ago

@tangxiaolang101 不知道你具体指的哪儿的对象拷贝,但有的api是是有额外的O(N),所以也需要注意

tangxiaolang101 commented 7 years ago

@ningt 就是Object.assign()

ningt commented 7 years ago

@tangxiaolang101 第三题里面N -> 数组长度,数组里面每个object的key的长度都是常数,所以Object.assign的时间复杂度应该是常数

tangxiaolang101 commented 7 years ago

@ningt 哦哦,对的。我刚才的意思是想表达,如果这里对象合并不能使用Object.assign,是不是只能用for去处理,然后整个的时间复杂度就提升了

ningt commented 7 years ago

@tangxiaolang101 在这道题用for跟用Object.assign其实没有区别,因为Object.assign的本质就是遍历object的key然后更新它的值。这道题里面每个object的key的数量都是常数,所以不会影响最后的Big O

cwsjoker commented 7 years ago

第一题我直接两个forEach不到10行的代码解决了

var arr = [];
data.rows.forEach((currentValue, index) => {
    var obj = {};
    currentValue.forEach((currentValueItem, indexItem) => {
        obj[data.metaData[indexItem]['name']] = currentValueItem;
    })
    arr.push(obj);
})
console.log(arr);

第三题暂时没有想到更好的办法

var arr_id = [];
var arr = a.concat(b);
var arr_result = [];
for (var i = 0; i < arr.length; i++) {
    arr_id.push(arr[i]['id']);
};
arr_id = [...new Set(arr_id)];
for (var i = 0; i < arr_id.length; i++) {
    var obj = {};
    for (var j = 0; j < arr.length; j++) {
        if (arr_id[i] == arr[j]['id']) {
            obj = Object.assign(obj, arr[j]);
            }
    };
    arr_result.push(obj);
};
console.log(arr_result);
leecz commented 7 years ago

第一题:

function transData ({rows, metaData}) {
  return rows.map(item => {
    let result = {}
    for (let i = 0, k = item.length; i < k; i++) {
      result[metaData[i].name] = item[i]
    }
    return result
  })
}
huzidaha commented 7 years ago

第一个我的解法,仅供参考:

data.rows.map((row) => row.reduce((rowData, value, i) => {
  rowData[data.metaData[i].name] = value
  return rowData
}, {}))

PS:第一题已经收录到:https://scriptoj.com/problems/32

大家可以检测一下自己做得对不对。

wzanbaichi commented 7 years ago
var data = {
        rows: [
            ["Lisa", 16, "Female", "2000-12-01"],
            ["Bob", 22, "Male", "1996-01-21"]
        ],
        metaData: [
            {name: "name", note: ''},
            {name: "age", note: ''},
            {name: "gender", note: ''},
            {name: "birthday", note: ''}
        ]
    };

    function func(data){
        let obj = {};
        let results = [];
        let arr = data.metaData.map(e=>e.name);
        for(let i = 0;i<data.rows.length;i++) {
            for(let j = 0;j<data.metaData.length;j++){
                obj[arr[j]]=data.rows[i][j];
            }

            results.push(JSON.parse(JSON.stringify(obj)))
        }
        console.log(results)
    }
    func(data);
beer-on-ice commented 7 years ago

第二题:

Weekly('09, 21, 2005')
function Weekly(a)  {
    // 将输入的时间转换成标准格式
    a = new Date(a)
    // 计算输入的时间在几月,在第几周
    let month = a.getMonth() + 1
    let week = a.getDate()/7 | 1
    // 只要本月前七天都不是周一,那本月1号往后的就计入本月,否则就计入上一月的第五周
    if(a.getDate() < 7) { // 前七天
        if (a.getDay() !== 1) {     // 第几周都不为周一
            month = a.getMonth()
            week = 5
        }
    }
    console.log(month,week)
}
OwenShi commented 6 years ago

第一题:

const formatData = (oriData)=>{
    let resultArr = [];
    let rows = oriData.rows;
    let metaData = oriData.metaData;
    for(let i=0;i<rows.length;i++){
        let temp = {};
        rows[i].forEach((value,index,array)=>{
            temp[metaData[index].name] = value
        });
        resultArr.push(temp);
    }
    console.log(resultArr);
};

第三题:

    const updateData = (mainData,subData)=>{
        for(let i=0;i<b.length;i++){
            let hasData = false;
            for(let j=0;j<a.length;j++){
                if(subData[i].id === mainData[j].id){
                    hasData = true;
                    console.log(mainData[j].id)
                    mainData[j] = Object.assign(mainData[j],subData[i])
                }
            }; 
            if(!hasData){
                mainData.push(subData[i]);
            }
        }
        return mainData;
    };
GoldenFlash commented 6 years ago
//二、写一个函数,判断给定的日期是几月的第几周,当月1日属于上一月的,该周计入上一月。   例如:
// 1)输入日期2016-02-01,返回结果为2-1,表示2016年2月1日属于2月的第一周;
// 2)输入日期2016-09-01,返回结果为8-5,表示2016年9月1日属于8月的第五周。

function whichDay(time){
    var time = new Date(time);
    var date = time.getDate();
    var month= 1;
    var week= 0;
    var end ;
    var weekday = time.getDay();
    if(weekday==0){
        weekday = 7;
        end = "日";
    }else{
        end = weekday
    };
    var remain = date%7
    var year = time.getFullYear();
    if(date>=7){
        if(remain<weekday){
            week = Math.floor(date/7)

        }else{
            week = Math.ceil(date/7)

        };
        month = time.getMonth()+1;
    }else if(date<7){
        if(remain<weekday){
            week = Math.floor(date/7)+5;
            month = time.getMonth();
        }else{
            week = Math.ceil(date/7);
            month = time.getMonth()+1;
        };
    };
    console.log(year+"第"+month+"月"+"第"+week+"周"+"星期"+end);

};
whichDay("2016-02-01");
whichDay("2016-09-01");
Stevenzwzhai commented 6 years ago

第二题

function getDays(year, month) {

    var days;
    //当月份为二月时,根据闰年还是非闰年判断天数
    if (month == 2) {
        days = year % 4 == 0 ? 29 : 28;

    } else if (!(month+'').replace(/(1|3|5|7|8|10|12)/, '')) {
        //月份为:1,3,5,7,8,10,12 时,为大月.则天数为31;
        days = 31;
    } else {
        //其他月份,天数为:30.
        days = 30;

    }
    return days;
}
function getWeek(date){
    let currDate = new Date(date.toString().replace('-', ','));
    let week = currDate.getDay()==0?7:currDate.getDay();
    let day = currDate.getDate();
    let month = currDate.getMonth()+1;
    let year = currDate.getFullYear();
    let preMonthDays = month>1?getDays(year, month-1):getDays(year-1, 12);
    if(day<8){
        if(week<=day){
            return `${year}年${month}月${day}日:${month}-1`
        }else{
            month = month>1?(month-1):12;
            return `${year}年${month+1}月${day}日:${(month)}-${(Math.floor((preMonthDays-week+1)/7)+1)}`;
        }
    }else{
        return `${year}年${month}月${day}日:${month}-${Math.floor((day-week+1)/7)+1}`
    }
}
YYJay commented 6 years ago

第一题

const data = {
    rows: [
      [ 'Lisa', 16, 'Female', '2000-12-01' ],
      [ 'Bob', 22, 'Male', '1996-01-21' ],
    ],
    metaData: [
      { name: 'name', note: '' },
      { name: 'age', note: '' },
      { name: 'gender', note: '' },
      { name: 'birthday', note: '' },
    ],
  }
const keyNames = data.metaData.map(item => item.name)
const newData = data.rows.map(row => {
    const rowObj = {}
    row.forEach((rowValue, index) => { rowObj[keyNames[index]] = rowValue })
    return rowObj
})
console.log(newData)
Raoul1996 commented 6 years ago

第一题:刚入手

const data = {
    rows: [
          ["Lisa", 16, "Female", "2000-12-01"],
          ["Bob", 22, "Male", "1996-01-21"]

    ],
    metaData: [
          {name: "name", note: ''},
          {name: "age", note: ''},
          {name: "gender", note: ''},
          {name: "birthday", note: ''}

    ]
}
const keys = [];
data.metaData.forEach(item=>{
    keys.push(item.name)
})
const res = data.rows.map(item=>{
    const tmp = {};
    for(let i = 0; i < item.length; i++) {
        tmp[keys[i]] = item[i]
    }
    return tmp
})
console.log(res)

获取 key 的操作不需要了

const res = data.rows.map(item=>{
    const tmp = {}
    for(let i = 0; i < item.length; i++) {
        tmp[data.metaData[i].name] = item[i]
    }
    return tmp
})

再改,参考了 胡子大哈 的解法,去仔细看了看 Array.prototype.reduce() 的用法

const res = data.rows.map(item => {
  item.reduce((rowData, value,i) => {
    rowData[data.metaData[i].name] = value
    return rowData
  }, {})
})
console.log(res)
zzz945 commented 6 years ago

第一题:

function convert (source) {
  return source.rows.map(row => {
    return row.reduce((acc, item, i) => {
      debugger
      acc[source.metaData[i].name] = item
      return acc
    }, {})
  })
}

第三题:

function arrToMap (arr, key='id') {
  return arr.reduce((acc, item) => {
    acc[item[key]] = item
    return acc
  }, {})
}

function mapToArr (obj) {
  return Object.keys(obj).map(k => obj[k])
}

function merge (a, b) {
  const aMap = arrToMap(a)
  b.forEach(item => {
    if (!aMap[item.id]) aMap[item.id] = {}
    return Object.assign(aMap[item.id] , item)
  })
  return mapToArr(aMap)
}
Cool-Star commented 5 years ago

function toChange(rows, metaData) {
  return rows.map(arry => {
    const obj = {};
    arry.forEach( (value,index) => {
      obj[metaData[index].name] = value;
    })
    return obj;
  })
}
JianJroh commented 3 years ago

第一题

function fn1(obj) {
    return obj.rows.map(row => {
        const item = {};
        row.forEach((rowItem, index) => {
            item[obj.metaData[index].name] = rowItem;
        })
        return item;
    });
}

第三题

function fn3(a, b) {
    const ab = a.map(itemA => {
        const otherObj = b.find(itemB => itemB.id === itemA.id);
        return Object.assign(itemA, otherObj);
    })
    const newAdds = b.filter(({ id }) => !ab.find(item => item.id === id));
    return ab.concat(newAdds);
}