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 · 38 comments

Comments

Projects
None yet
@willes
Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Collaborator

commented Dec 29, 2016

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

@RookieDay

This comment has been minimized.

Copy link

commented Dec 29, 2016

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

        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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link
Author

commented Dec 30, 2016

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

@henryzp

This comment has been minimized.

Copy link

commented Dec 30, 2016

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

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

这个逻辑判断是啥??

@henryzp

This comment has been minimized.

Copy link

commented Dec 30, 2016

@willes ,简单的

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

@zhangolve

This comment has been minimized.

Copy link

commented Dec 30, 2016

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

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Dec 30, 2016

@ningt


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

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

@ningt

This comment has been minimized.

Copy link

commented Dec 30, 2016

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

@kevinwulong

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Jan 2, 2017

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

This comment has been minimized.

Copy link

commented Feb 10, 2017

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

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

This comment has been minimized.

Copy link

commented Feb 14, 2017

第一题:

    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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Mar 22, 2017

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

@ningt

This comment has been minimized.

Copy link

commented Mar 22, 2017

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

@tangxiaolang101

This comment has been minimized.

Copy link

commented Mar 22, 2017

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

@ningt

This comment has been minimized.

Copy link

commented Mar 22, 2017

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

@tangxiaolang101

This comment has been minimized.

Copy link

commented Mar 22, 2017

@ningt 就是Object.assign()

@ningt

This comment has been minimized.

Copy link

commented Mar 22, 2017

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

@tangxiaolang101

This comment has been minimized.

Copy link

commented Mar 22, 2017

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

@ningt

This comment has been minimized.

Copy link

commented Mar 23, 2017

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

@cwsjoker

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Jul 18, 2017

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

This comment has been minimized.

Copy link

commented Sep 21, 2017

第二题:

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

commented Dec 7, 2017

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

This comment has been minimized.

Copy link

commented Jan 18, 2018

第二题

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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

This comment has been minimized.

Copy link

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)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.