使用阵列符号从一个JSON对象的多个级别属性检索(Multiple level attribute

2019-06-24 22:09发布

我有一个在这里精神上的征税问题,在这里我有在骨干网使用集合检索的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,
}

我想这个数据做的,就是将其过滤基于特定的属性,如Venue.Name或日期属性(它们是不同的深度进入的对象,可以为一些其他数据的更深两个级别) 。 我有一个主干内部集合下面的代码过滤,返回与适当过滤内容的新的集合:

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

这让我在哪个属性我想过滤的属性指定的,我希望它是等于为对象的任何深度的东西。 问题是,我真的不希望使用“EVAL”要做到这一点,但显然我不能用“[属性]”这样的事情“AwayTeam.TeamID”,因为这将无法正常工作。

有谁知道我可以用它来实现,而不使用eval此功能的方法?

Answer 1:

像这样的东西会让你遍历对象的层次结构,以找到一个值:

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');

你可以将其添加为您的方法Fixture对象:

Fixture = Backbone.Model.extend({
    findprop: function(path) {
        var obj = this.attributes,
            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;
    }
});

并用它来提取值

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;
    }));
}

和小提琴一起玩http://jsfiddle.net/nikoshr/wjWVJ/3/



Answer 2:

在JavaScript对象属性可以由方括号来访问,字符串标识符以及标准的点表示法。

换句话说,这样的:

fixture.attributes.something

是一样的:

fixture.attributes["something"]

您也可以在以方括号传递变量名,变量的值作为关键来检索。

所以,你可以更改您的代码如下:

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

当您在评论中指出,这只能处理一个级别的对象和属性。 为了得到嵌套的属性,你需要通过部分拆分“属性”变量和循环。 我喜欢@ nikoshr的该解决方案。



Answer 3:

我把nikoshr答案,并增加了一些递归风骚的它:

  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周期明智的,但我喜欢递归函数的时候都合适



Answer 4:

怎么样使用eval()是这样的:

 var myObject = { first: 'Some', last: 'Person', address: { city: 'Melbourne', country: 'Australia' } } var propPath = 'address.city'; var city = eval("myObject."+propPath); console.log(city); // = Melbourne 



文章来源: Multiple level attribute retrieval using array notation from a JSON object