【问题标题】:How do I find matching key/pair value from object inside of an array如何从数组内的对象中找到匹配的键/对值
【发布时间】:2020-05-17 12:07:45
【问题描述】:

我正在使用 Gatsby 开发无头 Shopify 商店,但在构建强大的产品选项选择器时遇到了一些麻烦。

我有一个看起来像这样的options 对象:

{
  extras: "Pouch only",
}

每个产品的key和value都不一样,所以我不知道value。

我有一个variants 数组,它将有一个与该对象匹配的键/值对。这是变体数组的形状:

[
  {
    extras: "Pouch only",
    ...otherValues,
  },
  {
    extras: "Add tassel",
    ...otherValues,
  },
  {
    extras: "Add charm",
    ...otherValues,
  },
  {
    extras: "Add tassel & charm",
    ...otherValues,
  },
  {
    sizes: "S",
    ...otherValues,
  },
  {
    sizes: "M",
    ...otherValues,
  },
  {
    sizes: "L",
    ...otherValues,
  },
  {
    sizes: "XL",
    ...otherValues,
  },
];

如果我提前知道变体的名称,我可以这样做:

const newVariant = variants.find((v) => {
  return v.extras === options.extras;
});

我如何在不知道密钥名称的情况下做同样的事情?

【问题讨论】:

    标签: javascript shopify


    【解决方案1】:

    使用Object.entries,您可以检索对象的键/值对,并检查.some(或.every,根据您的需要)是否匹配:

    const newVariant = variants.find((v) => Object.entries(options).some(([key, value]) => v[key] === value));
    

    【讨论】:

    • 感谢乔纳斯!这正是我想要做的。
    【解决方案2】:

    获取option 对象的条目并将它们字符串化。然后,在搜索variants 时,通过与先前字符串化的条目匹配的条目查找(或过滤):

    const optionsEntryVariants = Object.entries(options).map(JSON.stringify);
    const matchingVariants = variants.filter(
      variant => Object.entries(variant).some(
        entry => optionsEntryVariants.includes(JSON.stringify(entry))
      )
    );
    

    const options = {
      extras: "Pouch only",
    };
    
    const optionsEntryVariants = Object.entries(options).map(JSON.stringify);
    
    const variants = [
      {
        extras: "Pouch only",
        someOtherProp: 'someOtherVal',
      },
      {
        extras: "Add tassel",
        someOtherProp: 'someOtherVal',
      },
      {
        extras: "Add charm",
        someOtherProp: 'someOtherVal',
      },
      {
        extras: "Add tassel & charm",
        someOtherProp: 'someOtherVal',
      },
      {
        sizes: "S",
        someOtherProp: 'someOtherVal',
      },
      {
        sizes: "M",
        someOtherProp: 'someOtherVal',
      },
      {
        sizes: "L",
        someOtherProp: 'someOtherVal',
      },
      {
        sizes: "XL",
        someOtherProp: 'someOtherVal',
      },
    ];
    
    const matchingVariants = variants.filter(
      variant => Object.entries(variant).some(
        entry => optionsEntryVariants.includes(JSON.stringify(entry))
      )
    );
    
    console.log(matchingVariants);

    如果您需要匹配options 对象中的每个 键值对,而不是至少匹配一个,则将.some 更改为.every

    您可以通过创建一组字符串化条目而不是使用数组来使函数更高效:

    const optionsEntryVariants = new Set(
      Object.entries(options).map(JSON.stringify)
    );
    const matchingVariants = variants.filter(
      variant => Object.entries(variant).some(
        entry => optionsEntryVariants.has(JSON.stringify(entry))
      )
    );
    

    【讨论】:

      【解决方案3】:

      您可以遍历对象键进行检查。我认为这可以解决您的问题。

      const options = {
          extras: "Pouch only",
      };
      
      const otherValues = {};
      
      const variants = [
          {
              extras: "Pouch only",
              ...otherValues,
          },
          {
              extras: "Add tassel",
              ...otherValues,
          },
          {
              extras: "Add charm",
              ...otherValues,
          },
          {
              extras: "Add tassel & charm",
              ...otherValues,
          },
          {
              sizes: "S",
              ...otherValues,
          },
          {
              sizes: "M",
              ...otherValues,
          },
          {
              sizes: "L",
              ...otherValues,
          },
          {
              sizes: "XL",
              ...otherValues,
          },
      ];
      
      let optionsKey = '';
      for (const opKey in options) {
          optionsKey = opKey
      }
      
      const newVariant = variants.find((v) => {
          for (const vKey in v) {
              if (vKey === optionsKey) {
                  return v[vKey] === options[optionsKey];
              }
          }
      });

      【讨论】:

        【解决方案4】:

        您可以在其中使用filtersome 来执行此操作。方法如下:

        var data = data = [ { extras: "Pouch only" }, { extras: "Add tassel",size : 'SomeFilter' }, { extras: "Add charm" }, { extras: "Add tassel & charm", }, { sizes: "S" }, { sizes: "M", }, { sizes: "L" }, { sizes: "XL" }];
        
        filter = { extras: "Pouch only" }
        
        var objectToFilter = Object.entries(filter);
        
        result1 = data.filter(val=>objectToFilter.some(([k,v])=>val.hasOwnProperty(k) && val[k].includes(v)));
        
        filter = { extras: "Pouch only", size : 'SomeFilter'};
        
        var objectToFilter = Object.entries(filter);
        
        result2 = data.filter(val=>objectToFilter.some(([k,v])=>val.hasOwnProperty(k) && val[k].includes(v)));
        
        console.log(result2);

        另外,如果您想搜索过滤器中的所有值,some 可以替换为 every 方法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-01-08
          • 2019-08-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多