通过匹配对象的属性来选择对象数组,该属性也是数组

时间:2019-10-24 08:22:07

标签: javascript arrays sorting filtering data-retrieval

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

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

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

用户选择三个单词,然后我要搜索对象数组,并将这三个单词与每个数组的'keywords'属性进行匹配。然后我有一些显示逻辑:

  • 如果狗在所有三个用户选择的单词上都匹配,我只想退还那只狗。
  • 如果只有两个单词匹配的狗,那么我想带最多2条。
  • 如果只有一个2字狗,然后有多个1狗匹配项,则只需显示2字狗即可。
  • 如果只有1个单词的狗匹配项,则最多显示三个。

基本上,我不是在问要点,我可以弄清楚这一点,但理想情况下,我需要一排狗和每只狗旁边的火柴数。然后,我可以对此进行一些过滤。

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

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

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

2 个答案:

答案 0 :(得分:1)

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

通过以下代码片段,您将获得一个由狗名和所有匹配关键字组成的对象数组。

您可以轻松地从中获得匹配的关键字数量(使用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
)
...

或类似的

答案 1 :(得分:0)

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

import re

s = '1-4-1'
p = '\d-\d'
re.findall(p,s)

>> ['1-4']
>> but what I expected is: ['1-4', '4-1']

得分:

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

这不是最佳选择,但您可以随时进行修改。