在 javascript 中以正确的顺序过滤国家?
Filter countries in correct order in javascript?
我有一个国家/地区列表,我正在筛选这些国家/地区,以便根据输入的字词首先获得最佳匹配结果。我用两个例子来说明这个问题。搜索术语 unit
或 in
,您会发现预期的 returned 国家/地区名称顺序不正确。预期结果是 return 那些以 term
开头的国家/地区名称,在该优先级之后,return 个国家/地区与部分 term
字符串匹配。这是包含 terms
、当前结果和下面前 2 条评论中的预期结果的代码:
const {observable, action, computed} = mobx;
const {observer} = mobxReact;
@observer
class Country extends React.Component {
/*
1. Type term: 'unit'
Results:
- Emirates, The United Arab
- United States
- The United Kingdom
SHOULD BE:
- United States (this should be first since it starts with the term 'unit')
- The United Kingdom (this should be second since term 'unit' occurs in the name before "Emirates, The United Arab")
- Emirates, The United Arab
2. Type term: 'in'
Results:
- China
- India
- The United Kingdom
SHOULD BE:
- India (this should be first since it starts with the term 'in')
- China (this should be second since 'in' term occurs in the name before "The United Kingdom")
- The United Kingdom
*/
@observable filterTermValue = '';
@observable countriesList = [
{'slug': 'amsterdam', 'name': 'Amsterdam'},
{'slug': 'china', 'name': 'China'},
{'slug': 'uae', 'name': 'Emirates, The United Arab'},
{'slug': 'iceland', 'name': 'Iceland'},
{'slug': 'india', 'name': 'India'},
{'slug': 'usa', 'name': 'United States'},
{'slug': 'uk', 'name': 'The United Kingdom'},
{'slug': 'vienna', 'name': 'Vienna'}
];
@computed get filtered() {
let filteredList = this.countriesList.filter(
t=>t.name.toLowerCase().indexOf(this.filterTermValue)>-1
);
return filteredList;
}
render() {
return (
<div>
Term: <input placeholder="Start typing country"
onKeyUp={this.onChangeFilterTerm} />
{this.filtered.map(country =>
<div key={country.slug}>
<p>{country.name}</p>
</div>
)}
</div>
)
}
@action onChangeFilterTerm = (e) => {
this.filterTermValue = e.target.value.toLowerCase();
}
}
ReactDOM.render(
<Country />,
document.body
);
这里是fiddle
知道如何正确地将 filtered()
函数更新为 return 预期结果吗?
看来你需要在filtered
方法中对返回的数组进行排序。查看您在问题中提到的用例,我认为您可以按匹配开始的索引对数组进行排序。
因此,您的 filtered
方法可能如下所示:
@computed get filtered() {
return this.countriesList
.filter(t => t.name.toLowerCase().indexOf(this.filterTermValue) >-1)
.sort((a, b) => a.name.toLowerCase().indexOf(this.filterTermValue) - b.name.toLowerCase().indexOf(this.filterTermValue));
}
试试这个:
@computed get filtered() {
let filteredList = this.countriesList.filter(
t=>t.name.toLowerCase().indexOf(this.filterTermValue)>-1
).sort(
(a, b) => a.name.toLowerCase().indexOf(this.filterTermValue) - b.name.toLowerCase().indexOf(this.filterTermValue)
);
我有一个国家/地区列表,我正在筛选这些国家/地区,以便根据输入的字词首先获得最佳匹配结果。我用两个例子来说明这个问题。搜索术语 unit
或 in
,您会发现预期的 returned 国家/地区名称顺序不正确。预期结果是 return 那些以 term
开头的国家/地区名称,在该优先级之后,return 个国家/地区与部分 term
字符串匹配。这是包含 terms
、当前结果和下面前 2 条评论中的预期结果的代码:
const {observable, action, computed} = mobx;
const {observer} = mobxReact;
@observer
class Country extends React.Component {
/*
1. Type term: 'unit'
Results:
- Emirates, The United Arab
- United States
- The United Kingdom
SHOULD BE:
- United States (this should be first since it starts with the term 'unit')
- The United Kingdom (this should be second since term 'unit' occurs in the name before "Emirates, The United Arab")
- Emirates, The United Arab
2. Type term: 'in'
Results:
- China
- India
- The United Kingdom
SHOULD BE:
- India (this should be first since it starts with the term 'in')
- China (this should be second since 'in' term occurs in the name before "The United Kingdom")
- The United Kingdom
*/
@observable filterTermValue = '';
@observable countriesList = [
{'slug': 'amsterdam', 'name': 'Amsterdam'},
{'slug': 'china', 'name': 'China'},
{'slug': 'uae', 'name': 'Emirates, The United Arab'},
{'slug': 'iceland', 'name': 'Iceland'},
{'slug': 'india', 'name': 'India'},
{'slug': 'usa', 'name': 'United States'},
{'slug': 'uk', 'name': 'The United Kingdom'},
{'slug': 'vienna', 'name': 'Vienna'}
];
@computed get filtered() {
let filteredList = this.countriesList.filter(
t=>t.name.toLowerCase().indexOf(this.filterTermValue)>-1
);
return filteredList;
}
render() {
return (
<div>
Term: <input placeholder="Start typing country"
onKeyUp={this.onChangeFilterTerm} />
{this.filtered.map(country =>
<div key={country.slug}>
<p>{country.name}</p>
</div>
)}
</div>
)
}
@action onChangeFilterTerm = (e) => {
this.filterTermValue = e.target.value.toLowerCase();
}
}
ReactDOM.render(
<Country />,
document.body
);
这里是fiddle
知道如何正确地将 filtered()
函数更新为 return 预期结果吗?
看来你需要在filtered
方法中对返回的数组进行排序。查看您在问题中提到的用例,我认为您可以按匹配开始的索引对数组进行排序。
因此,您的 filtered
方法可能如下所示:
@computed get filtered() {
return this.countriesList
.filter(t => t.name.toLowerCase().indexOf(this.filterTermValue) >-1)
.sort((a, b) => a.name.toLowerCase().indexOf(this.filterTermValue) - b.name.toLowerCase().indexOf(this.filterTermValue));
}
试试这个:
@computed get filtered() {
let filteredList = this.countriesList.filter(
t=>t.name.toLowerCase().indexOf(this.filterTermValue)>-1
).sort(
(a, b) => a.name.toLowerCase().indexOf(this.filterTermValue) - b.name.toLowerCase().indexOf(this.filterTermValue)
);