Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用数组表示法从JSON对象检索多级属性_Javascript_Json_Backbone.js - Fatal编程技术网

Javascript 使用数组表示法从JSON对象检索多级属性

Javascript 使用数组表示法从JSON对象检索多级属性,javascript,json,backbone.js,Javascript,Json,Backbone.js,我在这里遇到了一个让人头疼的问题,我在主干网中使用集合检索了一个JSON对象。这就是对象的外观: { "MatchID": "00000001", "Date": "1970-01-01T00:00:00.000Z", "OriginalID": "", "Stage": { "StageNumber": "0", "StageType": "Stage Type" }, "Round": { "Ro

我在这里遇到了一个让人头疼的问题,我在主干网中使用集合检索了一个JSON对象。这就是对象的外观:

{
    "MatchID": "00000001",
    "Date": "1970-01-01T00:00:00.000Z",
    "OriginalID": "",
    "Stage": {
        "StageNumber": "0",
        "StageType": "Stage Type"
    },
    "Round": {
        "RoundNumber": "0",
        "Name": "Round Name"
    },
    "Leg": "1",
    "HomeTeam": {
        "TeamID": "0",
        "Name": "Home Team Name"
    },
    "AwayTeam": {
        "TeamID": "0",
        "Name": "Away Team Name"
    },
    "Venue": {
        "VenueID": "0",
        "Name": "Venu Name"
    },
    "Referee": null,
}
我想对这些数据做的是,根据特定属性对其进行过滤,例如场地.名称或日期属性(这些属性在对象中的深度不同,对于某些其他数据,深度可以超过两个级别)。我在主干集合中有以下代码,用于过滤并返回一个新集合,其中的内容经过适当过滤:

findWhere: function (Attribute, Value)
{
    return new Project.Collections.Fixtures(this.filter(function (fixture)
    {
        return eval('fixture.attributes.' + Attribute) == Value;
    }));
}
这允许我在属性中指定我要根据哪个属性进行过滤,以及对于对象的任何深度,我希望它等于什么。问题是,我真的不想用“eval”来做这件事,但显然我不能用“[Attribute]”来表示“AwayTeam.TeamID”之类的东西,因为它不起作用


有人知道我可以使用什么方法来实现这个功能而不使用eval吗?

类似的方法可以让您遍历对象的层次结构来找到一个值:

var x = {
    y: {
        z: 1
    }
};

function findprop(obj, path) {
    var args = path.split('.'), i, l;

    for (i=0, l=args.length; i<l; i++) {
        if (!obj.hasOwnProperty(args[i]))
            return;
        obj = obj[args[i]];
    }

    return obj;
}

findprop(x, 'y.z');
并使用它来提取值

var f = new Fixture();
f.findprop("HomeTeam.TeamID");
然后可以将
findWhere
方法重写为

findWhere: function (Attribute, Value)
{
    return new Project.Collections.Fixtures(this.filter(function (fixture){
        return fixture.findprop(Attribute) === Value;
    }));
}

可以通过方括号、字符串标识符以及标准点符号访问JavaScript对象中的

属性

换言之,这:

fixture.attributes.something

与此相同:

fixture.attributes[“某物”]

还可以将变量名传递到方括号中,变量的值用作检索的键

因此,您可以将代码更改为:

findWhere: function (Attribute, Value)
{
    return new Project.Collections.Fixtures(this.filter(function (fixture)
    {
        return fixture.attributes[Attribute] === Value;
    }));
}

正如您在注释中指出的,这只处理一个级别的对象和属性。要获得嵌套属性,您需要拆分“Attribute”变量并循环各个部分。我喜欢@Nikosh的解决方案。

我接受了Nikosh的答案,并添加了一些递归的技巧:

  var findprop = function (obj, path) {
        var args = (typeof path === 'string') ? path.split('.') : path,
            thisProperty = obj[args[0]];
        if (thisProperty === undefined) { return; } //not found

        args.splice(0, 1); //pop this off the array

        if (args.length > 0) { return findprop(thisProperty, args); } //recurse
        else {return thisProperty; }
    };

我不确定递归cpu周期是否有很多好处,但我喜欢适当的递归函数

像这样使用
eval()
怎么样:

var myObject={
第一:"一些",,
最后:"人",,
地址:{
城市:'墨尔本',
国家:'澳大利亚'
}
}
var propPath='address.city';
var city=eval(“myObject.”+propPath);

console.log(城市);//=墨尔本
谢谢你的回答,但这只适用于深入对象一层的属性,不是吗?是的,你是对的。我没有引起足够的注意。:)我喜欢@nikoshr的嵌套属性解决方案。谢谢你的评论,Derick:)是的,@nikoshr是一个我自己都不会想到的非常有趣的解决方案。只是在我的代码中实现了这一点,对我对象中的“n”级非常有效。谢谢如果你有证据证明这是有效的,我会投赞成票。懒得分析自己。
  var findprop = function (obj, path) {
        var args = (typeof path === 'string') ? path.split('.') : path,
            thisProperty = obj[args[0]];
        if (thisProperty === undefined) { return; } //not found

        args.splice(0, 1); //pop this off the array

        if (args.length > 0) { return findprop(thisProperty, args); } //recurse
        else {return thisProperty; }
    };