如何从数组内部的对象中找到匹配的键/对值

时间:2020-05-17 12:07:45

标签: javascript shopify

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

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

{
  extras: "Pouch only",
}

每种产品的键和值都不同,所以我不知道这些值。

我有一个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;
});

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

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:0)

获取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更改为{{1 }}。

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

.every

答案 2 :(得分:0)

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

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];
        }
    }
});

答案 3 :(得分:0)

您可以先使用filter,然后在其中使用some来执行此操作。方法如下:

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