【问题标题】:Selecting from an array of objects, by matching a property within, which is also an array从对象数组中选择,通过匹配其中的一个属性,该属性也是一个数组
【发布时间】:2020-02-20 13:02:36
【问题描述】:

原谅标题,但基本上这就是我想要做的:

我有一个对象数组,在这个例子中我们称它们为狗。每个对象看起来像这样:

    {
        name: "Poodle",
        keywords: ["Fluffy", "Intelligent", "Hypo-allergenic", "Loyal"]
    }

用户选择了三个词,然后我想搜索对象数组,并将这三个词与每个数组的“关键字”属性进行匹配。然后我有一些显示逻辑:

  • 如果狗在所有三个用户选择的词上都匹配,我只想退回那条狗。
  • 如果只有狗与 2 个单词匹配,那么我想带最多 2 条这样的狗。
  • 如果只有一个 2 字狗,然后有多个 1 狗匹配,则只显示 2 字狗。
  • 如果只有 1 个单词的 dog 匹配项,则最多显示其中三个。

基本上,我不是在问如何做要点,我可以弄清楚,但理想情况下,我需要一组狗和每只狗旁边的匹配数量。然后我可以对此进行一些过滤。

所以我需要一组狗名,总匹配数是这样的(当然,除非有更好的方法,否则我会全神贯注):

[
  ["Poodle", 2],
  ["Labrador", 2],
  ["Schpitz", 1],
  ["Setter", 0],
  ["Pit Bull", 0]
]

这听起来像是最好的方法,还是有更简单/更好的方法?

【问题讨论】:

  • 对我来说似乎没问题,也许如果你需要多次这样做,索引狗。
  • 谢谢,我已经将我真正想要实现的目标加粗了。

标签: javascript arrays sorting filtering data-retrieval


【解决方案1】:

不,这听起来不是最好的方法,因为您保存的东西本质上是一个数组结构中的对象。更好的方法是将结果对象数组作为结果。

使用下面的 sn-p 可以得到一个由狗名和所有匹配关键字组成的对象数组。

你可以很容易地从中获得匹配的关键字数量(通过使用result[i].matched.length),但我认为这更实用,因为你还可以显示实际匹配的关键字。

const data = [
  {
    name: "Poodle",
    keywords: ["Fluffy", "Intelligent", "Hypo-allergenic", "Loyal"]
  },
  {
    name: "Husky",
    keywords: ["Fluffy", "Cute", "Stuff", "IdkMuchAboutDogs"]
  }
];

const keywords = ["Fluffy", "Cute", "Intelligent"];

const result = data.map(dog => {
  return {
    dog: dog.name,
    matches: keywords.filter(keyword => dog.keywords.indexOf(keyword) !== -1)
  };
});

console.log(result);

如果你想在关键字比较上有更多的逻辑,你需要做类似的事情

...
matches: keywords.filter(keyword => 
   dog.keywords.filter(dogkeyword => 
      // Now you can compare those two keywords with more complex algorithms
      dogkeyword.toLowerCase() == keyword.toLowerCase()
   ).length !== 0
)
...

或类似的。

【讨论】:

    【解决方案2】:

    您可以根据自己的意愿生成分数:

    let dogs = [
        {
            name: "Poodle",
            keywords: ["Fluffy", "Intelligent", "Hypo-allergenic", "Loyal"]
        },
        {
            name: "Dog2",
            keywords: ["Fluffy", "Intelligent", "Hypo-allergenic",]
        },
        {
            name: "Dog3",
            keywords: ["Fluffy"]
        }
    ]
    

    评分:

    let scored = words => dogs.map(dog => {
        // you can add modification for 2 words term
        let score = dog.keywords.filter(kw => words.includes(kw)).length
    
        return {
            name: dog.name,
            score
        }
    })
    

    然后按最高分排序:

    let sorted = dogs => dogs.sort((a,b) => b.score - a.score)
    console.log(sorted(scored(['Fluffy', 'Loyal', "Intelligent"])))
    
    {name: "Poodle", score: 3}
    {name: "Dog2", score: 2}
    {name: "Dog3", score: 1}
    

    这不是最佳的,但您可以随时修改。

    【讨论】:

      猜你喜欢
      • 2021-09-19
      • 1970-01-01
      • 2022-11-21
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      • 2020-11-08
      • 2019-12-03
      • 1970-01-01
      相关资源
      最近更新 更多