Javascript 在nodejs中访问不同级别的嵌套JSON对象
我将数据存储在这样的变量中Javascript 在nodejs中访问不同级别的嵌套JSON对象,javascript,json,node.js,Javascript,Json,Node.js,我将数据存储在这样的变量中 var products = [ { place1:[ {id: 1, name: "choc1", price: 20}, {id: 2, name: "choc2", price: 30} ], place2:[ {id: 1, name: "coffee", price: 50} ], place3: [
var products = [
{
place1:[
{id: 1, name: "choc1", price: 20},
{id: 2, name: "choc2", price: 30}
],
place2:[
{id: 1, name: "coffee", price: 50}
],
place3: [
{id: 1, name: "oil1", price: 10},
{id: 2, name: "oil2", price: 60},
{id: 3, name: "oil3", price: 70}
]
}
];
我想编写一个get方法,以便它响应这个Url
http://myurl.com/place1/1
get方法的格式为
router.get('/:place/:id([0-9]{1,})', function(req, res){
// send the exact data as requested
}
我不明白的是如何验证链接。i、 例如,验证位置是否在products变量中,然后验证id是否存在于该product变量中,如果存在,则将其发送回服务器,否则发送错误响应。以下是使用点符号从对象获取嵌套值的函数:
/**
* Treating field name with dot in it as a path to nested value.
* For example 'settings.day' is path to { settings: { day: 'value' } }
*
* @param {{}} object Object where to look for a key
* @param {string} field Dot notated string, which is path to desired key
* @returns {*}
*/
getNestedValue = function (object, field) {
if (!object) {
return null;
}
var path = field.split('.');
while (path.length && (object = object[path.shift()]));
return object;
};
下面是访问嵌套JSON对象的方法:
if(products[0][req.params.place]) {
var place = products[0][req.params.place];
var resSent = false;
for(var obj in place) {
if(place[obj].id == req.params.id) {
resSent = true;
res.send(place[obj]);
}
}
if(!resSent) {
res.send(new Error('Not Found'));
}
} else {
res.send(new Error('Not Found'));
}
这是路由器的开始。我没有时间对产品进行过滤,因为结构有点奇怪。如果您使用它作为基础,您将需要做一些轻微的修改来使用节点中的req和res对象,但是正则表达式是合理的 编辑。。 看起来您更改了url reg,如果没有像前面的模式中那样指定任何正则表达式,我将留给您来解决如何用相应的正则表达式替换
:capture
,例如:id(regex)
请参阅下面的内联注释了解其工作原理
//将搜索字符串转换为正则表达式字符串并从字符串中捕获
常量regexify=str=>({
捕获:str.match(/:([a-z]+)/g).map(x=>x.replace(':',''),
reg:'^'+str.replace(//\//g,\\//')。replace(//:\w+/g,)+'$'
})
常量parse=x=>parseInt(x)==x?parseInt(x):x
类路由器{
构造函数(对象){
this.routes=[]
此.\uu onError=console.error.bind(console)
}
获取(uri,cb){
常量{captures,reg}=regexify(uri)
//创建新路线
这是推({
cb,
reg:新的RegExp(reg),
捕获
})
还这个
}
错误(cb){
这个。uu onError=cb
}
exec(uri/*,req,res*/){
//找到一条匹配的路线
constroute=this.routes.find(x=>x.reg.test(uri))
如果(!路线){
返回此消息。uu onError(`找不到路由:${uri}`)
}
常量参数=uri
.match(route.reg)//从url获取参数
.slice(1,route.captures.length+1)//删除不需要的值
.map(parse)//解析数字
//使用正确的参数调用路由回调
route.cb(
/*请求,
res*/
…参数
)
}
}
//实例化路由器
const路由器=新路由器
//创建路由器方法
路由器.get('/:place([a-z0-9]+)/:id([0-9]{1,}),(/*req,res,*/place,id)=>{
console.log(
'第一个路由回调:',
地点,身份证
)
})
路由器.get('/:place([a-z0-9]+),(/*req,res,*/place)=>{
console.log(
'第二个路由回调:',
地方
)
})
路由器错误(错误=>{
控制台错误(err)
})
//根据请求运行路由器
router.exec('/place1/1'/*req,res*/)
//下面是概念证明
router.exec('/place1'/*req,res*/)
router.exec('/1/fail'/*req,res*/)
请您在问题的上下文中更详细地解释一下,因为我不确定我是否理解如何应用此功能对不起,我的错误,误读了您的数据结构。如果你的place1
是这样一个对象,我的方法就行了{id\u 1:{id:1,name:'oil1',id\u 2:{id:1,name:'oil2'}}
那么你就可以像这样getNestedValue(products[0],[req.params.place,'id\u'+req.params.id].join('.')
不要使用-1,这是很可能的,ID将是456457458,而不是1,2,3。OP需要遍历产品数组以检查是否存在所需的id。我得到一个错误,即place变量不存在,然后它不存在于您的产品中,将place更改为“place1”,然后单击Run。结构与问题中所述完全相同。在req.params.places中,它表示未解析变量place。在路由器中,您是否可以记录req.params.place
?你看到了什么?
if(products[0][req.params.place]) {
var place = products[0][req.params.place];
var resSent = false;
for(var obj in place) {
if(place[obj].id == req.params.id) {
resSent = true;
res.send(place[obj]);
}
}
if(!resSent) {
res.send(new Error('Not Found'));
}
} else {
res.send(new Error('Not Found'));
}