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

问题描述 投票:0回答:4

我正在使用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;
});

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

javascript shopify
4个回答
0
投票

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

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

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更改为.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))
  )
);

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

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

© www.soinside.com 2019 - 2024. All rights reserved.