Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JS面试题求解 #21

Open
willes opened this issue Dec 29, 2016 · 39 comments
Open

JS面试题求解 #21

willes opened this issue Dec 29, 2016 · 39 comments

Comments

@willes
Copy link

willes commented Dec 29, 2016

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

{
 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
Copy link

zhangolve commented Dec 29, 2016

第一题做了一下,时间复杂度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
Copy link
Collaborator

FrankFang commented Dec 29, 2016

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

@RookieDay
Copy link

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

        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
Copy link

fonglezen commented Dec 30, 2016

第一题:

`

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
Copy link
Author

willes commented Dec 30, 2016

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

@henryzp
Copy link

henryzp commented Dec 30, 2016

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

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

这个逻辑判断是啥??

@henryzp
Copy link

henryzp commented Dec 30, 2016

@willes ,简单的

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

@zhangolve
Copy link

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

moment('2016-12-30', 'YYYY-MM-DD').format('W')

@ningt
Copy link

ningt commented Dec 30, 2016

第三题 @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
Copy link

@ningt


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

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

@ningt
Copy link

ningt commented Dec 30, 2016

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

@kevinwulong
Copy link

kevinwulong commented Dec 30, 2016

第一题

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
Copy link

450611 commented Dec 30, 2016

第一题

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
Copy link

LZ0211 commented Dec 30, 2016

//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
Copy link

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
Copy link

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

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
Copy link

第一题:

    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
Copy link

coolHt commented Mar 16, 2017

第一题:
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
Copy link

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

@ningt
Copy link

ningt commented Mar 22, 2017

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

@tangxiaolang101
Copy link

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

@ningt
Copy link

ningt commented Mar 22, 2017

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

@tangxiaolang101
Copy link

@ningt 就是Object.assign()

@ningt
Copy link

ningt commented Mar 22, 2017

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

@tangxiaolang101
Copy link

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

@ningt
Copy link

ningt commented Mar 23, 2017

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

@cwsjoker
Copy link

cwsjoker commented Apr 19, 2017

第一题我直接两个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
Copy link

leecz commented Apr 28, 2017

第一题:

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
Copy link

huzidaha commented May 14, 2017

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

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

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

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

@wzanbaichi
Copy link

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
Copy link

第二题:

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
Copy link

OwenShi commented Dec 6, 2017

第一题:

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
Copy link

//二、写一个函数,判断给定的日期是几月的第几周,当月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
Copy link

第二题

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
Copy link

YYJay commented Feb 27, 2018

第一题

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
Copy link

Raoul1996 commented Feb 27, 2018

第一题:刚入手

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
Copy link

zzz945 commented Mar 19, 2018

第一题:

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
Copy link

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

@JianJroh
Copy link

JianJroh commented Dec 3, 2020

第一题

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);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests