英文:
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_value
,nickname_id
和profile_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 = [{
"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('')
})
<!-- language: lang-html -->
<input>
<div id="results"></div>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论