Есть ли более простой способ или другой способ, которым я могу подойти к проверке этого флага в JavaScript?

#javascript #arrays #object

#javascript #массивы #объект

Вопрос:

У меня есть эта проверка, которая, кажется, работает только иногда, и я не знаю почему, если только я чего-то не вижу. Я хочу использовать переменную флага позже.

 var flag = false

var productos_grupo_promocion = [ { "idgrupo": 1, "cantidad_producto": 5 }, { "idgrupo": 6, "cantidad_producto": 1 } ]
            
var arr = [ { "idgrupo": 1, "cantidad": 5 }, { "idgrupo": 6, "cantidad": 1 } ]

productos_grupo_promocion.forEach(function (obj){

   var matched_elements = arr.filter(item => item.idgrupo == obj.idgrupo)

   matched_elements.forEach(function(item){
      if(parseInt(obj.cantidad_producto) == parseInt(item.cantidad)){
         flag = true
      }else{
         flag = false
      }
   }) 
})
 

Комментарии:

1. Должен flag ли единственный указывать, что было 1 совпадение? В этом случае используйте Array.some вместо forEach (в обоих случаях)

Ответ №1:

Текущая проблема, с которой вы сталкиваетесь, заключается в том, что в случае, если ваш последний продукт имеет совпадающие элементы, но не соответствует последнему matched_element , он установит значение flag to false .

Предполагая, что вы хотите flag установить true значение, как только у вас будет 1 совпадение, вы должны использовать Array.some .

Если вы хотите, чтобы все совпадало, вы должны использовать Array.every , но return false в случае, если их нет matched_elements .

Итак, я предполагаю, что вы хотите выйти раньше и просто измените свою логику на

 var productos_grupo_promocion = [{
  "idgrupo": 1,
  "cantidad_producto": 5
}, {
  "idgrupo": 6,
  "cantidad_producto": 1
}]

var arr = [{
  "idgrupo": 1,
  "cantidad": 5
}, {
  "idgrupo": 6,
  "cantidad": 1
}]

function hasMatch(promos, tags) {
  return promos.some(function(obj) {
    var matched_elements = tags.filter(item => item.idgrupo == obj.idgrupo);

    return matched_elements.some(function(item) {
      return parseInt(obj.cantidad_producto) == parseInt(item.cantidad);
    });
  });
}

console.log(hasMatch(productos_grupo_promocion, arr)); 

Поскольку это закончится, как только будет найдено 1 совпадение. Это то, чего, я полагаю, вы хотите достичь.

Поскольку я не совсем уверен, будет ли этого достаточно для будущего, почему бы не изменить, чтобы вы получали все элементы продвижения, которые действительно совпадают, скажем, следующим образом?

 const productos_grupo_promocion = [{
  "idgrupo": 1,
  "cantidad_producto": 5
}, {
  "idgrupo": 6,
  "cantidad_producto": 1
}, {
  "idgrupo": 6,
  "cantidad_producto": 5
}];

const arr = [{
  "idgrupo": 1,
  "cantidad": 5
}, {
  "idgrupo": 6,
  "cantidad": 1
}];

function getMatchingPromotions(promotions, tags) {
  const promoDict = promotions.reduce((map, promo) => map.set(promo.idgrupo, (map.get(promo.idgrupo) ?? []).concat( promo )), new Map());
  return tags.reduce((resultArr, tag) => {
    const matches = promoDict.get(tag.idgrupo);
    if (!matches) {
      return resultArr;
    }
    return resultArr.concat(matches.filter(p => p.cantidad_producto === tag.cantidad));
  }, []);
}

console.log( getMatchingPromotions(productos_grupo_promocion, arr) ); 

Сначала нужно сгруппировать все рекламные акции, а затем найти все совпадения для каждого тега.

Я не уверен, каким может быть ваш вариант использования впоследствии, поэтому, возможно, вторая версия переосмысливает ее, и в этом случае первая исправит вашу логику.

Комментарии:

1. Первое решение решило мою проблему, но с Array.every, спасибо!