Vue/Javascript—根据对象在另一个数组中的存在情况对其进行排序
我有两个数组,array1包含所有对象,array2基于搜索字符串过滤对象 目前,我正在向用户呈现array2(搜索字符串为空时,它将包含array1中的所有对象,但如果搜索字符串不为空,则仅返回过滤对象),但我希望显示所有对象并设置过滤对象(与搜索匹配的对象)的样式以不同的方式,将匹配搜索查询的对象保留在数组/列表的顶部,如果我还可以按字母顺序对匹配的对象进行排序,我很乐意这样做 以下是我如何根据搜索查询进行筛选:Vue/Javascript—根据对象在另一个数组中的存在情况对其进行排序,javascript,arrays,sorting,object,vuejs2,Javascript,Arrays,Sorting,Object,Vuejs2,我有两个数组,array1包含所有对象,array2基于搜索字符串过滤对象 目前,我正在向用户呈现array2(搜索字符串为空时,它将包含array1中的所有对象,但如果搜索字符串不为空,则仅返回过滤对象),但我希望显示所有对象并设置过滤对象(与搜索匹配的对象)的样式以不同的方式,将匹配搜索查询的对象保留在数组/列表的顶部,如果我还可以按字母顺序对匹配的对象进行排序,我很乐意这样做 以下是我如何根据搜索查询进行筛选: export default { name: "Region
export default {
name: "RegionSelector",
data: () => ({
searchRegionTextValue: "",
regions: [
{
country: "USA",
flag: "flag-en-us",
name: "United States",
language: "English",
},
{
country: "UK",
flag: "flag-en-gb",
name: "United Kingdom",
language: "English",
},
{
country: "DE",
flag: "flag-de",
name: "Germany",
language: " German",
},
],
}),
methods: {
// Used in my v-for in the template to style non-matched results differently
checkRegion(region) {
var isInArray =
this.filteredRegions.find(function(el) {
return el === region;
}) !== undefined;
return isInArray;
},
computed: {
filteredRegions() {
function compare(a, b) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}
let regions = this.regions.filter((region) => {
return (
region.name
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase()) != -1 ||
region.language
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase()) != -1
);
});
regions.sort(compare);
return regions;
},
},
};
导出默认值{
名称:“地区选民”,
数据:()=>({
searchRegionTextValue:“”,
区域:[
{
国家:“美国”,
国旗:“美国国旗”,
名称:“美国”,
语言:“英语”,
},
{
国家:“英国”,
国旗:“国旗en gb”,
名称:“联合王国”,
语言:“英语”,
},
{
国家:“德”,
旗帜:“德旗”,
名称:“德国”,
语言:“德语”,
},
],
}),
方法:{
//在模板中的“我的v-for”中使用,以对不匹配的结果进行不同的样式设置
检查区域(区域){
伊西纳雷变种=
this.filteredRegions.find(函数(el){
返回el==区域;
})!==未定义;
返回isInArray;
},
计算:{
过滤区域(){
功能比较(a、b){
如果(a.nameb.name)返回1;
返回0;
}
让regions=this.regions.filter((region)=>{
返回(
region.name
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase())!=-1||
地区语言
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase())!=-1
);
});
区域。排序(比较);
返回区;
},
},
};
在我的模板中,我以这种方式渲染它们(以显示所有对象,但样式不同):
{{region.name}
如何实现上述排序?您可以引入第二个
计算的
方法,该方法包含未匹配的对象,并对该数组执行另一个for loop
或
“可能”更有效,引入另一个属性将对象标记为匹配对象,并将该属性用于排序逻辑
computed: {
newregions() {
function compare(a, b) {
if (a.matched && !b.matched) return -1;
if (!a.matched && b.matched) return 1;
if (a.matched && b.matched) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
}
return 0;
}
let regions = this.regions.map((region) => ({
...region,
matched: region.name
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase()) != -1 ||
region.language
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase()) != -1
}));
regions.sort(compare);
return regions;
},
},
计算:{
新区域(){
功能比较(a、b){
如果(a.matched&&!b.matched)返回-1;
如果(!a.matched&&b.matched)返回1;
如果(a.匹配和b.匹配){
如果(a.nameb.name)返回1;
}
返回0;
}
让regions=this.regions.map((region)=>({
区域
匹配:region.name
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase())!=-1||
地区语言
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase())!=-1
}));
区域。排序(比较);
返回区;
},
},
然后在你的模板上
<div v-for="region in newregions">
<span
:class="region.matched ? 'matched-query' : 'unmatched-query'">
{{region.name}}
</span>
</div>
{{region.name}
您可以引入第二个计算的
方法,该方法包含未匹配的对象,并对该数组执行另一个for loop
或
“可能”更有效,引入另一个属性将对象标记为匹配对象,并将该属性用于排序逻辑
computed: {
newregions() {
function compare(a, b) {
if (a.matched && !b.matched) return -1;
if (!a.matched && b.matched) return 1;
if (a.matched && b.matched) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
}
return 0;
}
let regions = this.regions.map((region) => ({
...region,
matched: region.name
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase()) != -1 ||
region.language
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase()) != -1
}));
regions.sort(compare);
return regions;
},
},
计算:{
新区域(){
功能比较(a、b){
如果(a.matched&&!b.matched)返回-1;
如果(!a.matched&&b.matched)返回1;
如果(a.匹配和b.匹配){
如果(a.nameb.name)返回1;
}
返回0;
}
让regions=this.regions.map((region)=>({
区域
匹配:region.name
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase())!=-1||
地区语言
.toLowerCase()
.indexOf(this.searchRegionTextValue.toLowerCase())!=-1
}));
区域。排序(比较);
返回区;
},
},
然后在你的模板上
<div v-for="region in newregions">
<span
:class="region.matched ? 'matched-query' : 'unmatched-query'">
{{region.name}}
</span>
</div>
{{region.name}
使用spread操作符将原始数组附加到过滤数组的结果中,如下所示
[…过滤器区域(),…区域]
这会将匹配项添加到数组的开头,接下来我们将从数组中删除重复项,只需将new Set()
包装在数组周围即可,如下所示
const newRegions=新集合([…filteredRegions(),…regions])
您可以像这样将其转换为普通数组
const newRegions=[…新集合([…filteredRegions(),…regions])]
参见下面的示例代码:
const regions=[
{
国家:“美国”,
国旗:“美国国旗”,
名称:“美国”,
语言:“英语”,
},
{
国家:“英国”,
国旗:“国旗en gb”,
名称:“联合王国”,
语言:“英语”,
},
{
国家:“德”,
旗帜:“德旗”,
名称:“德国”,
语言:“德语”,
},
{
国家:“NG”,
国旗:“ng旗”,
名称:“尼日利亚”,
语言:“英语”,
},
]
功能比较(a、b){
如果(a.nameb.name)返回1;
返回0;
}
函数filteredRegions(查询='Nigeria'){
让区域=区域。过滤器((区域)=>{
返回(
region.name
.toLowerCase()
.indexOf(query.toLowerCase())!=-1 | | region.language
.toLowerCase()
.indexOf(query.toLowerCase())!=-1
);