过滤嵌套数组中的字段

huangapple go评论51阅读模式
英文:

JS Filter array inside array by fields

问题

[
    {
        "profile_id": 1,
        "nicknames": [
            {
                "nickname_id": 230,
                "nickname_value": "Rob",
                "admin_id": 5,
                "created_at": "2023-01-08T13:20:24.000000Z",
                "updated_at": "2023-01-08T13:20:24.000000Z"
            },
            {
                "nickname_id": 231,
                "nickname_value": "Wel",
                "admin_id": 5,
                "created_at": "2023-01-08T13:20:32.000000Z",
                "updated_at": "2023-01-08T13:20:32.000000Z"
            }
        ]
    },
    {
        "profile_id": 12,
        "nicknames": [
            {
                "nickname_id": 232,
                "nickname_value": "Pol",
                "admin_id": 5,
                "created_at": "2023-01-08T14:06:14.000000Z",
                "updated_at": "2023-01-08T14:06:14.000000Z"
            }
        ]
    }
]

我想要一个示例HTML输入,其中我可以提供一些值。我需要该脚本通过字段nickname_valuenickname_idprofile_id仅从一个输入字段中筛选数组。我知道如何在数组内部进行筛选,但我不知道如何添加一个profile_id的筛选条件。

英文:

Json structure:

[
    {
        "profile_id": 1,
        "nicknames": [
            {
                "nickname_id": 230,
                "nickname_value": "Rob",
                "admin_id": 5,
                "created_at": "2023-01-08T13:20:24.000000Z",
                "updated_at": "2023-01-08T13:20:24.000000Z"
            },
            {
                "nickname_id": 231,
                "nickname_value": "Wel",
                "admin_id": 5,
                "created_at": "2023-01-08T13:20:32.000000Z",
                "updated_at": "2023-01-08T13:20:32.000000Z"
            }
        ]
    },
    {
        "profile_id": 12,
        "nicknames": [
            {
                "nickname_id": 232,
                "nickname_value": "Pol",
                "admin_id": 5,
                "created_at": "2023-01-08T14:06:14.000000Z",
                "updated_at": "2023-01-08T14:06:14.000000Z"
            }
        ]
    }
]

I would like to have for example HTML input where I may provide some value. I need that script filter array by fields nickname_value, nickname_id, and profile_id from only one input field. I know how to filter inside an array but I don't have an idea to add a filter by profile_id.

答案1

得分: 1

问题变得简单,如果我们能清楚地说明我们所指的匹配,并且如果我们将谓词描述为函数,代码就会变得更简单(也更易读)。

这里有一个提议,如果profile_id完全匹配或任何昵称匹配,那么对象就匹配输入。如果nickname_id完全匹配,或者输入是nickname_value的不区分大小写前缀,则昵称匹配。

基于属性名称,这些标准似乎是一个合理的猜测,但实际上取决于应用程序。

// 回答对象是否与输入“匹配”。假设输入是一个字符串
function match(object, input) {
  if (object.profile_id === +input) return true;

  const nicknameMatch = n => n.nickname_id === +input ||
    n.nickname_value.toLowerCase().startsWith(input.toLowerCase());
  return object.nicknames.some(nicknameMatch)
}

有了这个,过滤器可以直接使用...

const results = input.filter(object => match(object, input))

一旦这个功能正常工作,我们可能会考虑效率的问题。一个想法是在对象中缓存一些信息,比如字符串化的ID,以及昵称ID和小写昵称值的数组。如果这些对象对一个可能会增长的应用程序很重要,我们可以将文字对象转换为一个class的实例,并为它们提供一个match方法。

英文:

The problem gets simple if we can clearly state what we mean by a match, and the code gets simpler to write (and read) if we describe the predicates as functions.

Here's a proposal that says an object matches an input if the profile_id matches exactly or if any of its nicknames match. A nickname matches if the nickname_id matches exactly or if the input is a case-insensitive prefix of the nickname_value.

These criteria are a reasonable-seeming guess based on the prop names, but really up to the app.

// answer whether the object "matches" the input. presumes input is a string
function match(object, input) {
  if (object.profile_id === +input) return true;

  const nicknameMatch = n => n.nickname_id === +input ||
    n.nickname_value.toLowerCase().startsWith(input.toLowerCase());
  return object.nicknames.some(nicknameMatch)
}

With this, filter works straightforwardly...

const results = input.filter(object => match(object, input))

Once this is working, we might want to think about efficiency. One idea would be to cache a few things with the object, like stringified ids, and arrays of nickname ids and lowercase nickname values. If these objects are important to an app that's apt to grow, we could convert the literal objects to instances of a class, and give them a match method.

答案2

得分: 1

const data = [{
  "profile_id": 1,
  "nicknames": [{
      "nickname_id": 230,
      "nickname_value": "Rob",
      "admin_id": 5,
      "created_at": "2023-01-08T13:20:24.000000Z",
      "updated_at": "2023-01-08T13:20:24.000000Z"
    },
    {
      "nickname_id": 231,
      "nickname_value": "Wel",
      "admin_id": 5,
      "created_at": "2023-01-08T13:20:32.000000Z",
      "updated_at": "2023-01-08T13:20:32.000000Z"
    }
  ]
},
{
  "profile_id": 12,
  "nicknames": [{
    "nickname_id": 232,
    "nickname_value": "Pol",
    "admin_id": 5,
    "created_at": "2023-01-08T14:06:14.000000Z",
    "updated_at": "2023-01-08T14:06:14.000000Z"
  }]
}]

document.querySelector('input').addEventListener('input', ({
  target: {
    value
  }
}) => {
  const matches = data.filter(
    profile => profile.profile_id.toString() === value || profile.nicknames.some(
      nickname => nickname.nickname_id.toString() === value || nickname.nickname_value === value
    )
  )
  document.querySelector('#results').innerHTML = matches.map(profile => profile.profile_id).join('')
})
<input>
<div id="results"></div>
英文:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-js -->

const data = [{
    &quot;profile_id&quot;: 1,
    &quot;nicknames&quot;: [{
        &quot;nickname_id&quot;: 230,
        &quot;nickname_value&quot;: &quot;Rob&quot;,
        &quot;admin_id&quot;: 5,
        &quot;created_at&quot;: &quot;2023-01-08T13:20:24.000000Z&quot;,
        &quot;updated_at&quot;: &quot;2023-01-08T13:20:24.000000Z&quot;
      },
      {
        &quot;nickname_id&quot;: 231,
        &quot;nickname_value&quot;: &quot;Wel&quot;,
        &quot;admin_id&quot;: 5,
        &quot;created_at&quot;: &quot;2023-01-08T13:20:32.000000Z&quot;,
        &quot;updated_at&quot;: &quot;2023-01-08T13:20:32.000000Z&quot;
      }
    ]
  },
  {
    &quot;profile_id&quot;: 12,
    &quot;nicknames&quot;: [{
      &quot;nickname_id&quot;: 232,
      &quot;nickname_value&quot;: &quot;Pol&quot;,
      &quot;admin_id&quot;: 5,
      &quot;created_at&quot;: &quot;2023-01-08T14:06:14.000000Z&quot;,
      &quot;updated_at&quot;: &quot;2023-01-08T14:06:14.000000Z&quot;
    }]
  }
]

document.querySelector(&#39;input&#39;).addEventListener(&#39;input&#39;, ({
  target: {
    value
  }
}) =&gt; {
  const matches = data.filter(
    profile =&gt; profile.profile_id.toString() === value|| profile.nicknames.some(
      nickname =&gt; nickname.nickname_id.toString() === value || nickname.nickname_value === value
    )
  )
  document.querySelector(&#39;#results&#39;).innerHTML = matches.map(profile =&gt; profile.profile_id).join(&#39;&#39;)
})

<!-- language: lang-html -->

&lt;input&gt;
&lt;div id=&quot;results&quot;&gt;&lt;/div&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年1月9日 00:56:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/75049690.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定