我正在操作一个对象数组并从中提取唯一的对象。我从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);
不确定如何调和这两者。
答案 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。