J'ai un tableau d'un objet comme celui-ci
[
{
'a': 10,
elements: [
{
'prop': 'foo',
'val': 10
},
{
'prop': 'bar',
'val': 25
},
{
'prop': 'test',
'val': 51
}
]
},
{
'b': 50,
elements: [
{
'prop': 'foo',
'val': 30
},
{
'prop': 'bar',
'val': 15
},
{
'prop': 'test',
'val': 60
}
]
},
]
Ce dont j'ai besoin, c'est d'additionner la propriété Val
lorsque prop
est foo
. Je dois donc effectuer une recherche parmi les éléments et obtenir tous les objets où prop
est foo
. Avec cet objet, je devrais résumer la propriété val
.
J'ai essayé d'utiliser plusieurs combinaisons de _.find
, _.pick
et ainsi de suite, mais je n'obtiens pas le bon résultat. Est-ce que quelqu'un peut m'aider?
Voici une solution qui flatte les éléments puis filtres le résultat pour obtenir les éléments requis avant sommant la propriété val:
var result = _.chain(data)
.map('elements') // pluck all elements from data
.flatten() // flatten the elements into a single array
.filter({prop: 'foo'}) // exatract elements with a prop of 'foo'
.sumBy('val') // sum all the val properties
.value()
Le chaînage est un moyen d'appliquer une séquence d'opérations à certaines données avant de renvoyer une valeur. L'exemple ci-dessus utilise un chaînage explicite, mais pourrait être écrit (peut-être devrait l'être) à l'aide d'un chaînage implicite:
var result = _(data)
.map('elements')
.flatten()
.filter({prop: 'foo'})
.sumBy('val');
J'ai créé une bibliothèque que vous pouvez utiliser: https://github.com/dominik791/obj-traverse
La méthode findAll()
devrait résoudre votre problème. Le premier paramètre est un objet racine, pas un tableau, vous devriez donc le créer en premier:
var rootObj = {
name: 'rootObject',
elements: [
{
'a': 10,
elements: [ ... ]
},
{
'b': 50,
elements: [ ... ]
}
]
};
Ensuite, utilisez la méthode findAll()
:
var matchingObjects = findAll( rootObj, 'elements', { 'prop': 'foo' } );
La variable matchingObjects
stocke tous les objets avec prop
égal à foo
. Et à la fin, calculez votre somme:
var sum = 0;
matchingObjects.forEach(function(obj) {
sum += obj.val;
});
Vous pouvez parcourir les données et obtenir la somme. Essayez ceci:
var arr=[
{
'a': 10,
elements: [
{
'prop': 'foo',
'val': 10
},
{
'prop': 'bar',
'val': 25
},
{
'prop': 'test',
'val': 51
}
]
},
{
'b': 50,
elements: [
{
'prop': 'foo',
'val': 30
},
{
'prop': 'bar',
'val': 15
},
{
'prop': 'test',
'val': 60
}
]
}
];
var sum=0;
for(x in arr){
for(i in arr[x]['elements']){
if(arr[x]['elements'][i]['prop'] == 'foo'){
sum=sum+arr[x]['elements'][i]['val'];
}
}
}
console.log(sum);
UTILISER LE FILTRE:
var arr=[
{
'a': 10,
elements: [
{
'prop': 'foo',
'val': 10
},
{
'prop': 'bar',
'val': 25
},
{
'prop': 'test',
'val': 51
}
]
},
{
'b': 50,
elements: [
{
'prop': 'foo',
'val': 30
},
{
'prop': 'bar',
'val': 15
},
{
'prop': 'test',
'val': 60
}
]
}
];
var sum=0;
arr.filter(function (person) {
person['elements'].filter(function(data){
if (data.prop == "foo"){
sum=sum+data.val;
}
});
});
console.log(sum);
Vous pouvez utiliser _.eachDeep method de deepdash:
var sum = 0;
_.eachDeep(obj,
function(value, key, path, depth, parent) => {
sum += (key == 'prop' && value == 'foo' && parent.val) || 0;
}
);
voici un exemple pour votre cas