Open willes opened 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 控制台测试可行
代码外面加上三个 ` 可以变好看 @zhangolve @willes 我帮你俩都加上了
简单实现,先做第一道题目,下面是我的解法:
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"}
第一题:
`
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;
}
`
@fonglezen @RookieDay 请问第三题怎么弄呢
话说第二题,我愣是看不懂。。
你2016年9月1号,在8月份的日历里面也是算第五周啊??那为什么2月1号算2月的第一周,9月1号算8月的第五周?
这个逻辑判断是啥??
@willes ,简单的
遍历b数组,拿它单个对象里面的id去找a里面的对象,然后for in添加,相同的属性continue
@henryzp 第二题要是能够用库的话,只是获取当年的第几周其实就简单了。然而并不是,总觉得第二题真要是面试出的话很坑,并不像是考js,而是考算法,当然算法是基础。
moment('2016-12-30', 'YYYY-MM-DD').format('W')
第三题 @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);
}
});
@ningt
const map = a.reduce((acc, curr, index) => {
acc[curr.id] = index;
return acc;
}, {});
这里是什么意思?干嘛要这样做呢?
@fonglezen 建一个反向查找的表 id -> index,不然对于b数组里面每个id都需要遍历一遍a数组,最后复杂度就变成O(n^2)了。
第一题
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)
}
}
第一题
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);
//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;
}
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);
}
}
})
})
第一小题,写的不完美,但是勉强能运行。
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);
第一题:
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);
感觉自己写的好蠢
第一题: 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);
应该没有错吧。。。不知道写的规范不规范。。
@ningt 这种问题一般是不是不会去考虑兼容性,如果考虑兼容性,设计时间复杂度是不是就上去了?
@tangxiaolang101 个人感觉这种题应该跟兼容性没太大关系,假如面试官说你不可以用 reduce
,你用 for
也是一样的。
@ningt 哦哦,也对。那对象拷贝这个问题,如果是兼容性的化,时间复杂度是不是就只能是O(n^2)了
@tangxiaolang101 不知道你具体指的哪儿的对象拷贝,但有的api是是有额外的O(N),所以也需要注意
@ningt 就是Object.assign()
@tangxiaolang101 第三题里面N -> 数组长度,数组里面每个object的key的长度都是常数,所以Object.assign的时间复杂度应该是常数
@ningt 哦哦,对的。我刚才的意思是想表达,如果这里对象合并不能使用Object.assign,是不是只能用for去处理,然后整个的时间复杂度就提升了
@tangxiaolang101 在这道题用for跟用Object.assign其实没有区别,因为Object.assign的本质就是遍历object的key然后更新它的值。这道题里面每个object的key的数量都是常数,所以不会影响最后的Big O
第一题我直接两个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);
第一题:
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
})
}
第一个我的解法,仅供参考:
data.rows.map((row) => row.reduce((rowData, value, i) => {
rowData[data.metaData[i].name] = value
return rowData
}, {}))
PS:第一题已经收录到:https://scriptoj.com/problems/32
大家可以检测一下自己做得对不对。
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);
第二题:
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)
}
第一题:
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;
};
//二、写一个函数,判断给定的日期是几月的第几周,当月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");
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}`
}
}
第一题
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)
第一题:刚入手
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)
第一题:
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)
}
function toChange(rows, metaData) {
return rows.map(arry => {
const obj = {};
arry.forEach( (value,index) => {
obj[metaData[index].name] = value;
})
return obj;
})
}
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);
}
一、从某数据库接口得到如下值:
rows是数据,metaData是对数据的说明。现写一个函数,将上面的Object转化为期望的数组:
二、写一个函数,判断给定的日期是几月的第几周,当月1日属于上一月的,该周计入上一月。例如: 1)输入日期2016-02-01,返回结果为2-1,表示2016年2月1日属于2月的第一周; 2)输入日期2016-09-01,返回结果为8-5,表示2016年9月1日属于8月的第五周。
三、数组
数组
写一个函数按id用b更新a,期望得到的结果为: