使用jQuery grep时保留属性

时间:2014-08-08 16:38:08

标签: jquery arrays grep

我正在操作一个对象数组并从中提取唯一的对象。我从inArray开始,但我正在测试一个嵌套属性,所以它不能很好地工作。 grep将测试嵌套属性,但它不允许我在结束最终数组之前更改对象。

让我演示一下:

这是(类似于)我的起始对象数组: 它有我不在算法中使用的属性(例如:foo,legs.type),但它们的存在使对象结构复杂化,从而使解决方案变得复杂。

 var critters = [
    {'legs':{'num':4,'type':'paw'},     'species':'cat',    'foo':11 },
    {'legs':{'num':4,'type':'paw'},     'species':'dog',    'foo':11 },
    {'legs':{'num':2,'type':'foot'},    'species':'human',  'foo':23 },
    {'legs':null,                       'species':'fish',   'foo':3 }
];

这是我最后想要的对象数组:

// walkingCritterTypes = [
//   { 'legs':{'num':4,'type':'paw'},     'species':['cat','dog'],    'foo':11 },
//   { 'legs':{'num':2,'type':'foot'},    'species':['human'],        'foo':23 }
// ];

这是我使用inArray的方法。 +是允许我在将它传递给最终数组之前抓住项目并操纵它。 - 这是不起作用的,因为它需要测试一个嵌套属性。

var walkingCritterTypesA = [];
angular.forEach(critters,function(critter,i){
    if (angular.isObject(critter.legs)) {// ditch critters with null legs
        var exists = $.inArray(critter.legs.num, walkingCritterTypes.legs.num);
        //this does not work
        // I want it to find if walkingCritterTypes.legs.num already exists
        if (exists){
            // but if it did magically work, it would allow me to 
            // operate on the walkingCritterTypes array item, 
            // adding this critter's properties (eg species) to the final array
            walkingCritterType[i].species.push(critter.species);
        }
        else{
            // this is a new type, so I'll add it
            walkingCritterType = {};
            walkingCritterType.legs = critter.legs;
            walkingCritterType.species = critter.species;
            walkingCritterType.foo = critter.foo;
            walkingCritterTypesA.push(walkingCritterType);
        }
    }
});
console.log(walkingCritterTypesA);

这是我使用grep的方法。 +是它可以搜索嵌套属性。 - 这是1]我不确定如何编写测试,以及2]它的魔力 - 它只是在最后给我一个新阵列,而没有给我机会操纵它

angular.forEach(critters,function(critter,i){
    if (angular.isObject(critter.legs)) {// I don't care about critters with null legs
        walkingCritterTypesG2 = $.grep(walkingCritterTypesG, function(el,i){
            return // er what? compare it to itself??
        })
    }
});


console.log(walkingCritterTypesG);

不确定如何调和这两者。

1 个答案:

答案 0 :(得分:0)

嗯,我有一个解决方案,但它不够优雅。我将重复测试所需的属性复制到它自己的数组中。现在我可以使用inArray了。

$scope.walkingCritterTypes = [];
$scope.walkingCritterTypeIDs = []; // <----- ID in its own shallow array
angular.forEach($scope.critters,function(critter,i){
    if (angular.isObject(critter.legs)) {// drop critters with null legs
        // walkingCritterTypes.legs.num already exists in final array?
        var existingType = $.inArray(critter.legs.num, $scope.walkingCritterTypeIDs); // <----- test against ID
        if (existingType >= 0){
            // add this critter's properties (eg species) to the final array
            $scope.walkingCritterTypes[existingType].species.push(critter.species);
        }
        else{
            // this is a new type, so I'll add it to the final array
            var walkingCritterType = {};
            walkingCritterType.legs = critter.legs;
            walkingCritterType.species = new Array(critter.species);
            walkingCritterType.foo = critter.foo;
            $scope.walkingCritterTypes.push(walkingCritterType);
            $scope.walkingCritterTypeIDs.push(critter.legs.num); //  <----- add to ID array
        }
    }
});
console.log($scope.walkingCritterTypes);

在将数据存入数组之前,看看我是如何对有效项进行操作的?这就是为什么我不能用grep。