2017-10-20 9 views
1

J'utilise souvent Array.prototype.filter et je m'attends seulement à ce qu'un seul élément soit véridique.Accéder efficacement aux retours d'un seul élément Array.prorotype.filter

Comme filtre retourne un tableau de résultats, je me trouve avoir besoin d'accéder à toujours cet élément, donc je fais quelque chose comme

knownRefundLogics.filter((refundLogic) => this.hasTag(refundLogic.underscoredName))[0] 

suppose que:

knownRefundLogics = [{ 
    "underscoredName": "express_full_refund", 
    "camelized": "expressFullRefund" 
}, { 
    "underscoredName": "express_partial_refund", 
    "camelized": "expressPartialRefund" 
}, { 
    "underscoredName": "express_no_refund", 
    "camelized": "expressNoRefund" 
}] 

et hasTag() une méthode qui ne un includes() sur un tableau pour l'élément refundLogic.

Existe-t-il une méthode plus appropriée pour cela, en utilisant l'opérateur spread par exemple? Par ailleurs, je sais que je pourrais éventuellement scinder mes méthodes de telle sorte que seule une valeur true ou false soit retournée, mais je trouve que c'est un peu une solution trop complexe.

+0

'Array.prototype.some()', 'Array.prototype.every()' – Andreas

+0

Vous pouvez utiliser [Array.prototype.reduce()] (https: // développeur .mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce), il est garanti de retourner la valeur unique – Flying

+0

mais recommanderiez-vous reduce() pour filtrer/vérifier la véracité des valeurs? –

Répondre

1

Vous pouvez utiliser la fonction Array#find, qui renvoie le premier élément, qui réussit la condition donnée. En outre, il est plus rapide que filter, car filter itère sur tous les éléments et vous obtenez seulement le premier. find trouve le premier élément correspondant et casse la boucle.

De l'exemple que vous pouvez le voir, il itère 2 fois au lieu de 3.

const knownRefundLogics = [{ 
 
    "underscoredName": "express_full_refund", 
 
    "camelized": "expressFullRefund" 
 
}, { 
 
    "underscoredName": "express_partial_refund", 
 
    "camelized": "expressPartialRefund" 
 
}, { 
 
    "underscoredName": "express_no_refund", 
 
    "camelized": "expressNoRefund" 
 
}]; 
 

 
const foundItem = knownRefundLogics.find(item => { 
 

 
    console.log('Iteration'); 
 
    
 
    return item.camelized === 'expressPartialRefund'; 
 

 
}); 
 

 
console.log(foundItem);

+0

le problème avec .find est que vous devez utiliser un polyfill mais je vais accepter la réponse que je n'ai pas spécifié dans ma question. –

2

Utilisez Array#find() au lieu - chaque fois que le prédicat retourne true, l'itération est arrêté, et l'élément correspondant (pas un tableau) est renvoyé immédiatement:

const knownRefundLogics = [{"underscoredName":"express_full_refund","camelized":"expressFullRefund"},{"underscoredName":"express_partial_refund","camelized":"expressPartialRefund"},{"underscoredName":"express_no_refund","camelized":"expressNoRefund"}]; 
 

 
const demoHasTag = (t) => t === 'express_partial_refund'; 
 

 
const result = knownRefundLogics.find((refundLogic) => demoHasTag(refundLogic.underscoredName)); 
 

 
console.log(result);

0

Si vous voulez une solution sans polyfill, la bonne vieille boucle est votre ami.

var knownRefundLogics = [{ 
 
    "underscoredName": "express_full_refund", 
 
    "camelized": "expressFullRefund" 
 
}, { 
 
    "underscoredName": "express_partial_refund", 
 
    "camelized": "expressPartialRefund" 
 
}, { 
 
    "underscoredName": "express_no_refund", 
 
    "camelized": "expressNoRefund" 
 
}]; 
 

 
var selected; 
 
for(var i = 0; i < knownRefundLogics.length; i++){ 
 
    let current = knownRefundLogics[i]; 
 
    if(current.underscoredName === 'express_partial_refund'){ 
 
    selected = current; 
 
    break; 
 
    } 
 
} 
 

 
console.log(selected);

Avec cela, vous pouvez écrire votre propre polyfill de lumière.

function findInArray(array, test){ 
 
    for(var i = 0; i < array.length; i++){ 
 
    if(test(array[i], i, array)) return array[i]; 
 
    } 
 
} 
 

 
var knownRefundLogics = [{ 
 
    "underscoredName": "express_full_refund", 
 
    "camelized": "expressFullRefund" 
 
}, { 
 
    "underscoredName": "express_partial_refund", 
 
    "camelized": "expressPartialRefund" 
 
}, { 
 
    "underscoredName": "express_no_refund", 
 
    "camelized": "expressNoRefund" 
 
}]; 
 

 
console.log(findInArray(knownRefundLogics, function(item, index, array){ 
 
    return item.underscoredName === "express_partial_refund"; 
 
}));

+0

ou un .forEach je suppose? Je n'ai toujours pas entendu d'avis en obtenant automatiquement le premier et seul élément d'une fonction de filtre –

+0

Contrairement à une simple boucle, vous ne pouvez pas interrompre la boucle forEach. – Techniv

+0

Pour l'avis sur le filtre. Il a le même inconvénient que le forEach. Il ne peut pas être interrompu et il sera forcé de traverser tout le tableau. Donc, si vous avez juste besoin de récupérer la première occurrence qui vérifie votre condition, ce n'est pas très efficace. – Techniv