JavaScript通过父节点ID递归生成JSON树:
实现思路:通过递归实现(第一次递归的时候查询出所有的父节点,然后通过当前父节点id不断地去查询所有子节点,直到递归完毕返回)
// 模拟数据
const ary = [
{ id: '1', name: '11', parent_id: '' },
{ id: '2', name: '22', parent_id: '' },
{ id: '3', name: '33', parent_id: '' },
{ id: '11', name: '11-11', parent_id: '1' },
{ id: '12', name: '11-12', parent_id: '1' },
{ id: '21', name: '22-21', parent_id: '2' },
{ id: '31', name: '33-31', parent_id: '3' },
]
/**
* 递归通过父节点ID生成树结构
* 思路:
* 1. 第一次递归的时候查询出所有的父节点
* 2. 然后通过当前父节点id不断地去查询所有子节点,直到递归完毕返回
* @param {
String} pid 父节点id
*/
function getTrees(pid='') {
if(!pid) {
// 如果没有父id(第一次递归的时候)将所有父级查询出来
return ary.filter(item => !item.parent_id).map(item => {
// 通过父节点ID查询所有子节点
item.children = getTrees(item.id)
return item
})
} else {
return ary.filter(item => item.parent_id === pid).map(item => {
// 通过父节点ID查询所有子节点
item.children = getTrees(item.id)
return item
})
}
}
console.log(getTrees())
/** 输出:
* [{
* id: "1",
* name: "11",
* parent_id: 0,
* children: [
* {
* id: "11",
* name: "11-11",
* parent_id: '1',
* }
* ]
* },......]
*/
JS修改数组中对象属性名称
后端响应给前端的数组中对象属性名称不是我们想要的,可通过此方法进行转换。
转换过后,原响应体并未发生改变。
const data = {
totalEmelents: 100,
list: [
{ id: 0, name: "a" },
{ id: 1, name: "b" },
{ id: 2, name: "c" },
]
}
const myList = data.list.map(item => {
return {
key: item.id,
value: item.name
}
});
console.log(...data.list)
console.log(...myList)
{
id: 0, name: 'a'} {
id: 1, name: 'b'} {
id: 2, name: 'c'}//原来的
{
key: 0, value: 'a'} {
key: 1, value: 'b'} {
key: 2, value: 'c'}//修改之后的
修改children里面的属性名
使用for循环方法
const list = [
{ id: 0, name: "a", children: { id: 100, name: 'dd' } },
{ id: 1, name: "b" },
{ id: 2, name: "c" }
];
for (let i = 0; i < list.length; i++) {
if (list[i].children) {
list[i].children.pid = list[i].children.id;
delete list[i].children.id;
}
}
console.log(list);
打印结果:[
{ id: 0, name: 'a', children: { name: 'dd', pid: 100 } },
{ id: 1, name: 'b' },
{ id: 2, name: 'c' }
]
使用map方法
const list = [
{ id: 0, name: "a", children: { id: 100, name: 'dd' } },
{ id: 1, name: "b" },
{ id: 2, name: "c" }
];
const modifiedList = list.map(({ id, name, children }) => ({
id,
name,
children: children ? { pid: children.id, name: children.name } : undefined
}));
console.log(modifiedList);
打印结果[
{ id: 0, name: 'a', children: { name: 'dd', pid: 100 } },
{ id: 1, name: 'b' },
{ id: 2, name: 'c' }
]
练手试题
题目、答案拷自牛客网,答案不是最简的,不过刚好可以运用到JS对象方法。
++ 字符串字符统计(牛客网)
题目描述:
统计字符串中每个字符的出现频率,返回一个 Object,key 为统计字符,value 为出现频率
- 不限制 key 的顺序
- 输入的字符串参数不会为空
- 忽略空白字符
输入:
‘hello world’
输出:
{h: 1, e: 1, l: 3, o: 2, w: 1, r: 1, d: 1}
答案:(需要更多?)
function count(str) {
//用正则表达式去除空白符
var newStr = str.replace(/\s/g,"");
//console.log(newStr) //helloworld
var res={};
for(var i=0 ; i<newStr.length; i++){
//循环字符串,判断是否已存在对象中
if(newStr.charAt(i) in res){
res[newStr.charAt(i)]++;
}
else{
res[newStr.charAt(i)] = 1;
}
}
return res;
}
count('hello world')
++ 时间格式化输出(牛客网)
题目描述:
按所给的时间格式输出指定的时间
格式说明
对于 2014.09.05 13:14:20
yyyy: 年份,2014
yy: 年份,14
MM: 月份,补满两位,09
M: 月份, 9
dd: 日期,补满两位,05
d: 日期, 5
HH: 24制小时,补满两位,13
H: 24制小时,13
hh: 12制小时,补满两位,01
h: 12制小时,1
mm: 分钟,补满两位,14
m: 分钟,14
ss: 秒,补满两位,20
s: 秒,20
w: 星期,为 [‘日’, ‘一’, ‘二’, ‘三’, ‘四’, ‘五’, ‘六’] 中的某一个,本 demo 结果为 五
输入:
formatDate(new Date(1409894060000), ‘yyyy-MM-dd HH:mm:ss 星期w’)
输出:
2014-09-05 13:14:20 星期五
答案:(需要更多?)
function formatDate(t,str){
var obj = {
yyyy:t.getFullYear(),
yy:(""+ t.getFullYear()).slice(-2),
M:t.getMonth()+1,
MM:("0"+ (t.getMonth()+1)).slice(-2),
d:t.getDate(),
dd:("0" + t.getDate()).slice(-2),
H:t.getHours(),
HH:("0" + t.getHours()).slice(-2),
h:t.getHours() % 12,
hh:("0"+t.getHours() % 12).slice(-2),
m:t.getMinutes(),
mm:("0" + t.getMinutes()).slice(-2),
s:t.getSeconds(),
ss:("0" + t.getSeconds()).slice(-2),
w:['日', '一', '二', '三', '四', '五', '六'][t.getDay()]
};
return str.replace(/([a-z]+)/ig,function($1){
return obj[$1]});
}
formatDate(new Date(1409894060000), 'yyyy-MM-dd HH:mm:ss 星期w')
//"2014-09-05 13:14:20 星期五"
项目中遇到过
++ 数组去重
题目描述:
为 Array 对象添加一个去除重复项的方法
输入:
[false, true, undefined, null, NaN, 0, 1, {}, {}, ‘a’, ‘a’, NaN]
输出:
[false, true, undefined, null, NaN, 0, 1, {}, {}, ‘a’]
答案:(需要更多?)
Array.prototype.uniq = function () {
var resArr = [];
var flag = true;
for(var i=0;i<this.length;i++){
if(resArr.indexOf(this[i]) == -1){
if(this[i] != this[i]){ //排除 NaN
if(flag){
resArr.push(this[i]);
flag = false;
}
}else{
resArr.push(this[i]);
}
}
}
return resArr;
}
var arr = [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN];
arr.uniq()//[false, true, undefined, null, NaN, 0, 1, {}, {}, 'a']
++将字符串转换为驼峰格式
题目描述:
css 中经常有类似 background-image 这种通过 - 连接的字符,通过 javascript 设置样式的时候需要将这种样式转换成 backgroundImage 驼峰格式,请完成此转换功能
- 以 - 为分隔符,将第二个起的非空单词首字母转为大写
- -webkit-border-image 转换后的结果为 webkitBorderImage
输入:
‘font-size’
输出:
fontSize
答案:(需要更多?)
function cssStyle2DomStyle(sName) {
let sNameArr = sName.split(''); //["f", "o", "n", "t", "-", "s", "i", "z", "e"]
if(sNameArr.indexOf('-')==0){
sNameArr.splice(0,1)//删除连接符'-'
}
for(var i=1; i<sNameArr.length; i++){
if(sNameArr[i] == '-'){
sNameArr.splice(i,1);//删除连接符'-'
sNameArr[i]=sNameArr[i].toUpperCase();//将首个单词转换成大写
}
}
return sNameArr.join('');
}
cssStyle2DomStyle('font-size')//fontSize