我有一个需要排序的JSON对象数组。该数组需要按两个不同的属性进行排序。首先,应使用found
属性按字母顺序对数组进行排序。其次,应该对数组进行排序,以使website
属性以siteOrder
中指定的相同顺序降序。
var siteOrder = ['facebook', 'twitter', 'reddit', 'youtube', 'instagram'];
var data = [
{found: 'booker', website: 'reddit'},
{found: 'john', website: 'facebook'},
{found: 'walter', website: 'twitter'},
{found: 'smith', website: 'instagram'},
{found: 'steve', website: 'youtube'},
{found: 'smith', website: 'facebook'},
{found: 'steve', website: 'twitter'},
{found: 'john', website: 'instagram'},
{found: 'walter', website: 'youtube'}
];
/* Example output: Sorted output by found, respecting the order of the websites specified
{found: 'booker', website: 'reddit'},
{found: 'john', website: 'facebook'},
{found: 'john', website: 'instagram'},
{found: 'smith', website: 'facebook'},
{found: 'smith', website: 'instagram'},
{found: 'steve', website: 'twitter'},
{found: 'steve', website: 'youtube'},
{found: 'walter', website: 'twitter'},
{found: 'walter', website: 'youtube'}
*/
我可以使用以下找到的属性按字母顺序对它们进行排序:
data.sort(function(a, b) {
var textA = a.found.toUpperCase();
var textB = b.found.toUpperCase();
return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
});
但是我不知道如何使其也遵守网站的指定顺序。
答案 0 :(得分:2)
如果找到的两个对象的文本相同,则比较siteOrder中两个对象的网站索引。
data.sort(function (a, b) {
var textA = a.found.toUpperCase();
var textB = b.found.toUpperCase();
var foundOrder = (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
if (foundOrder === 0) {
var indexA = siteOrder.indexOf(a.website);
var indexB = siteOrder.indexOf(b.website);
return (indexA < indexB) ? -1 : (indexA > indexB) ? 1 : 0;
}
return foundOrder;
});
答案 1 :(得分:0)
var siteOrder = ['facebook', 'twitter', 'reddit', 'youtube', 'instagram'];
var data = [
{found: 'booker', website: 'reddit'},
{found: 'john', website: 'facebook'},
{found: 'walter', website: 'twitter'},
{found: 'smith', website: 'instagram'},
{found: 'steve', website: 'youtube'},
{found: 'smith', website: 'facebook'},
{found: 'steve', website: 'twitter'},
{found: 'john', website: 'instagram'},
{found: 'walter', website: 'youtube'}
];
// For performance, add a property that is the index of the website in the list
data.forEach(o => o.siteIndex = siteOrder.indexOf(o.website));
// If the `found` of each object is the same, then use the index of the
// website as the sort criteria, otherwise compare the `found` props
data.sort((a, b) =>
a.found === b.found ? a.siteIndex - b.siteIndex : a.found.localeCompare(b.found)
);
// Remove the optimization property
data.forEach(o => delete o.siteIndex);
console.log(data);
答案 2 :(得分:0)
var siteOrder = ["facebook", "twitter", "reddit", "youtube", "instagram"];
var data = [{
found: "booker",
website: "reddit"
},
{
found: "john",
website: "facebook"
},
{
found: "walter",
website: "twitter"
},
{
found: "smith",
website: "instagram"
},
{
found: "steve",
website: "youtube"
},
{
found: "smith",
website: "facebook"
},
{
found: "steve",
website: "twitter"
},
{
found: "john",
website: "instagram"
},
{
found: "walter",
website: "youtube"
}
];
const result = data.sort((a, b) => {
const textA = a.found.toUpperCase();
const textB = b.found.toUpperCase();
if (textA < textB) {
return -1;
} else if (textA > textB) {
return 1;
}
const siteA = siteOrder.indexOf(a.website);
const siteB = siteOrder.indexOf(b.website);
if (siteA < siteB) {
return -1;
} else if (siteA > siteB) {
return 1;
} else {
return 0;
}
});
console.log(result);
答案 3 :(得分:0)
这可以通过指定一个排序处理程序来实现;
found
字段比较一对项目。如果项目不匹配,请分别返回-1
或1
found
字段均匹配,则根据相同的方式(返回-1
,1
或0
)对这些项目对进行排序website
数组中每个项目的sortOrder
字段的索引上可以实现如下所示:
var siteOrder = ['facebook', 'twitter', 'reddit', 'youtube', 'instagram'];
var data = [
{found: 'booker', website: 'reddit'},
{found: 'john', website: 'facebook'},
{found: 'walter', website: 'twitter'},
{found: 'smith', website: 'instagram'},
{found: 'steve', website: 'youtube'},
{found: 'smith', website: 'facebook'},
{found: 'steve', website: 'twitter'},
{found: 'john', website: 'instagram'},
{found: 'walter', website: 'youtube'}
];
data.sort((itemA, itemB) => {
const foundA = itemA.found.toLowerCase();
const foundB = itemB.found.toLowerCase();
/* Sort based on found (primary criteria) */
if(foundA < foundB) return -1;
if(foundA > foundB) return 1;
/* If foundA and foundB are equivilant, sort
based on website (secondary criteria) */
const websiteA = itemA.website.toLowerCase();
const websiteB = itemB.website.toLowerCase();
/* Find index of each site, relative to the siteOrder array */
const siteA = siteOrder.indexOf(websiteA);
const siteB = siteOrder.indexOf(websiteB);
/* Sort items that have matching found values, by the index that site
values occour in the siteOrder */
website values in
if(siteA < siteB) return -1;
if(siteA > siteB) return 1;
return 0;
});
console.log(data);