【问题标题】:Prevent adding an object to an array that already exists防止将对象添加到已存在的数组中
【发布时间】:2021-02-20 21:43:58
【问题描述】:

我有一个调用fetchGames 函数的输入字段:

fetchGames: debounce(function (searchQuery) {
  this.gallery.forEach((item, index) => {
    if (item.Key.includes(searchQuery)) {
      this.filteredGallery.push(item.Key)
    } else {
      this.filteredGallery.splice(index, 1)
    }
  })
}, 500)

这类作品。我的 gallery 数组他的 3 个对象:

gallery: ['bali', 'brass', 'eclipse']

当我输入a 时,它会将balibrass 添加到filterGallery 数组中。

当我将l(使al)添加到输入时,函数会按预期从数组中删除brass,但它会向数组中添加另一个bali,因为item.Key 也包含@ 987654334@.

如何防止将对象添加到数组中已存在的数组中?

ps。使用 Vue2,您不能在 Set 对象上使用 v-for (afaik)。

【问题讨论】:

  • 尝试使用Set 而不是Array,这样您就可以直接调用set.add 而不必担心重复
  • 是的,只需使用Set 或添加另一个if 语句来检查该字符串是否已在filteredGallery 中。就我个人而言,我会缩短它并使用包含 this.filteredGallery = this.gallery.map((item) => item.Key).filter((item) => item.includes(searchQuery)) 之类的过滤器
  • 也许我应该说我正在使用 Vue2 循环通过 filteredGallery 并且看起来你不能通过 Set 对象进行 v-for 。感谢@DominikMatis 成功了。智能映射和过滤结果并将其返回给数组变量。如果您想将其放在答案中,我会很乐意接受。
  • 我会为这个画廊创建一个控制它的类
  • @PeterBoomsma ...关于最近提供的数组变异方法还有什么问题吗?

标签: javascript vuejs2


【解决方案1】:

您可以在每次输入更改中删除您的 arr,或者添加另一个 if 语句,该语句将检查 filterGallery 并且不推送它已经包含的项目

【讨论】:

  • 是的,考虑过这一点,但是我会在一个循环中出现一个循环,这不是很好。清除数组是一种选择。
【解决方案2】:

基于 OP 提供的代码,并考虑到限制,一种方法是始终改变 filteredGallery。每次搜索时,首先通过将其length 设置为零来清空/重置数组。然后通过提供刚刚清空的filteredGallery 作为回调收集数组来减少gallery 数组,其中一个确实推入新搜索的所有匹配项...

fetchGames: debounce(function (searchQuery) {
  this.filteredGallery.length = 0; // reset.

  this.gallery.reduce((arr, { Key }) => {
    if (Key.includes(searchQuery)) {

      arr.push(Key); // push into collector.
    }
    return arr;

  }, this.filteredGallery); // collector.

}, 500)

为了证明建议的方法,上面提供的代码稍微修改为可执行的 sn-p ...

function fetchGamesAtBoundComponent(searchQuery) {
  this.filteredGallery.length = 0; // reset.

  this.gallery.reduce((arr, { Key }) => {
    if (Key.includes(searchQuery)) {

      arr.push(Key); // push into collector.
    }
    return arr;

  }, this.filteredGallery); // collector.
}

const component = {
  gallery: [
    { Key: 'bali' },
    { Key: 'brass' },
    { Key: 'eclipse' },
  ],
  filteredGallery: ['foo', 'bar', 'baz'],
};
const fetchGames =
  fetchGamesAtBoundComponent.bind(component);

console.log(
  "default state ...",
  { component }
);
fetchGames('a');

console.log(
  "fetchGames('a') ...",
  { component }
);
fetchGames('al');

console.log(
  "fetchGames('al') ...",
  { component }
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

【讨论】:

  • @PeterBoomsma ...关于上述方法还有什么问题吗?
【解决方案3】:

与其他 cmets 一样,Set 可以解决问题。您可以使用以下模式来确保生成的数组不包含重复项。

[...new Set([...currentValues, newValue])]

注意 Set 是如何分布到一个数组中的,所以你应该很好地使用 v-for

【讨论】:

  • Set 似乎不适用于 Vue2。不能将 v-for 与 Set 对象一起使用。
  • 您将 Set 分散到一个数组中,所以它应该没关系。
【解决方案4】:

首先,您将数组映射为仅包含 Key 属性,然后根据包含特定子字符串的属性进行过滤

此处的示例脚本:

this.filteredGallery = this.gallery.map((item) => item.Key).filter((item) => item.includes(searchQuery))

【讨论】:

    猜你喜欢
    • 2021-09-27
    • 1970-01-01
    • 2020-12-09
    • 2012-09-12
    • 2017-08-20
    • 2019-12-23
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    相关资源
    最近更新 更多