我有一个要过滤的国家/地区列表,首先要根据输入项获得最佳匹配结果。我用2个例子来说明这个问题。搜索术语unit
或in
,您会看到预期返回的国家名称顺序不正确。预期的结果是返回以term
开头的国家/地区名称,并在该优先级之后返回部分term
字符串匹配的国家/地区。以下是包含terms
,当前结果和下面前两个注释中的预期结果的代码:
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()
函数以正确返回预期结果?
答案 0 :(得分:1)
似乎您需要使用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));
}
答案 1 :(得分:0)
尝试一下:
@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)
);