2016.7
前言
工作中会经常遇到对数据的处理,入行一个多月,我目前接触到的技术,也是日常工作中常用的,是利用ajax来请求接口和后台对接进行数据交互,数据的形式是JSON格式。这就需要我们能够熟练地对JavaScript的对象和数组进行操作处理,尤其是对复杂的JSON嵌套形式的对象进行操作,完成我们想要达成的目的。在代码方面,目前工作上采用的依然是JavaScript最有名的类库jQuery。
打算以后对工作中遇到以及平时接触到的一些数据处理问题的实现方法进行记录,作为个人思考和学习的笔记整理总结,更多的是一些实际问题的代码实例而非理论知识,主要是方便今后再次遇到类似问题时进行查阅。作为新手前端,有的问题也许会很简单,甚至记录的也并非最优解。
遍历对象和数组
问题一
这是我在新手交流群里看到的一道题,是FreeCodeCamp上的。
有以下数据:
var contacts = [
{
"firstName": "Akira",
"lastName": "Laine",
"number": "0543236543",
"likes": ["Pizza", "Coding", "Brownie Points"]
},
{
"firstName": "Harry",
"lastName": "Potter",
"number": "0994372684",
"likes": ["Hogwarts", "Magic", "Hagrid"]
},
{
"firstName": "Sherlock",
"lastName": "Holmes",
"number": "0487345643",
"likes": ["Intriguing Cases", "Violin"]
},
{
"firstName": "Kristian",
"lastName": "Vos",
"number": "unknown",
"likes": ["Javascript", "Gaming", "Foxes"]
}
];
类似于保存了一个通讯录,需要写一个lookUp函数来查询这个通讯录,lookUp有两个参数:firstName和prop。如果它们都存在,函数返回prop属性对应的值;如果firstName 值不存在,返回 "No such contact";如果prop 属性不存在,返回 "No such property"。 eg. lookUp('Harry', 'number');
一开始我把这个问题想得复杂了,主要还是自己基础知识不扎实和经验上的欠缺。
先看给出的数据形式,contacts是一个数组作为通讯录,里面的每一项都是一个对象(通讯录中的人),对象包含了名字等信息。题目是要通过一个函数传递人的名字和一个属性,在通讯录中查找,如果没有这个名字,返回一个信息;如果传递的属性名不存在,又返回另一个信息;如果都能查找到(有这个人,这个人也有这个属性),则返回传递属性的值。这里面有一个潜在的逻辑是,如果查到没有这个名字,就不再做后面的判断,直接返回查无此人,当能查到这个人,再做其是否有这个属性的判断,同样地,没有这个属性,直接返回查无此信息。
最开始我的思路是,将所有的firstName的value提取出来组成一个新的数组,循环新数组来看参数是否匹配里面的某一项。这固然是一个办法,不过要是对遍历有些理解,能灵活运用,就可以直接用更简单的方式来实现了,于是想到了如下方法:
function lookUp(firstName, prop){
for(var i in contacts){
if(contacts[i].firstName == firstName){
contacts[firstName] = contacts[i];
}
}
if(!contacts[firstName]){
return 'No such contact';
}
if(!contacts[firstName][prop]){
return 'No such property';
}
return contacts[firstName][prop];
}
实现不难,用到了一个下标替换来定位参数匹配的对象。
问题二
这个是在工作上遇到的,是对一个区域ID查询输出该区域的省市区全称,中国那么多地方,这个数据量还是挺大的,仔细看了下JSON结构,大致可以概括为下面那样:
var data = [
{ id : '1', name : 'AAA省', childs : [
{ id : '101', name : 'AA市', childs :[
{ id : '10101', name : 'A区' },
{ id : '10102', name : 'B区' }
]},
{ id : '102', name : 'BB县', childs :[
{ id : '10201', name : 'A市' },
{ id : '10202', name : 'B市' }
]}
]},
{ id : '2', name : 'BBB省', childs : [
{ id : '201', name : 'CC市', childs :[
{ id : '20101', name : 'C区' },
{ id : '20102', name : 'D区' }
]},
{ id : '202', name : 'DD县', childs :[
{ id : '20201', name : 'C市' },
{ id : '20202', name : 'D市' }
]}
]},
{ id : '3', name : 'CCC市', childs : [
{ id : '301', name : '市辖区', childs :[
{ id : '30101', name : 'E区' },
{ id : '30102', name : 'F区' }
]},
{ id : '302', name : 'DD县', childs :[
{ id : '30201', name : 'E市' },
{ id : '30202', name : 'F市' }
]}
]}
];
比如给我们一个id20202
,我们需要输出的最终值就是BBB省DD县D市
,这个我是用笨办法,层层遍历嵌套来解决的。
function getArea(areaId){
outLoop:
for(var i in data){
for(var j in data[i]['childs']){
for(var k in data[i]['childs'][j]['childs']){
if(areaId == data[i]['childs'][j]['childs'][k]['id']){
var province = data[i]['name'],
city = data[i]['childs'][j]['name'],
district = data[i]['childs'][j]['childs'][k]['name'];
console.log(province + city + district);
break outLoop;
}
}
}
}
}
getArea(20202); //BBB省DD县D市
需要注意两点:遍历对象提取键值对要用引号;拿到目标后终止所有嵌套循环的办法,单纯break只能终止本层循环。