JavaScript:根据排列顺序对数组进行排序



我有一个N个元素的列表,其中有一个三种颜色的数组,如下所示:

[
{ id: 1, colors: ['Red', 'Blue', 'White'] },
{ id: 2, colors: ['Red', 'Blue', 'Blue'] },
{ id: 3, colors: ['Red', 'Red', 'White'] },
{ id: 4, colors: ['Red', 'Red', 'Red'] }
]

我想根据这个优先级顺序对它们进行排序,例如:

[Red,Red,Red]
[Red,Red,X]
[Red,X,Red]
[Red,X,X]
[X,Red,Red]
[X,Red,X]
[X,X,Red]

其中"X"表示任何其他颜色,而不是我所表示的颜色,在本例中为"红色"。

因此,这个例子的预期输出是:

[
{ id: 1, colors: ['Red', 'Red', 'Red'] },
{ id: 2, colors: ['Red', 'Red', 'White'] },
{ id: 3, colors: ['Red', 'Blue', 'White'] },
{ id: 4, colors: ['Red', 'Blue', 'Blue'] }
]

有什么办法吗?

我试着找到重复的数组,并根据颜色对父数组进行排序,但我需要考虑优先级顺序。

elements.sort((a, b) => {
const colorDupsA = findDuplicates(a.colors);
const colorDupsB = findDuplicates(b.colors);
return colorDupsB.length - colorDupsA.length;
});

或者,使用索引数组srt,可以按以下方式执行:

const arr=[
{id: 1,colors: ['Red', 'Blue', 'White']},
{id: 1,colors: ['Red', 'Blue', 'Blue']},
{id: 1,colors: ['Red', 'Red', 'White']},
{id: 1,colors: ['Red', 'Red', 'Red']}];
const srt=arr.map((e,i)=>[i,e.colors.map(c=>c=="Red"?"1":"0").join("")])
console.log(srt.sort((a,b)=>b[1]-a[1]).map(([i])=>arr[i]));

你甚至可以把它简化为一行:

arr.map((e,i)=>[i,e.colors.map(c=>c=="Red"?"1":"0").join("")])
.sort((a,b)=>b[1]-a[1]).map(([i])=>arr[i])

sort方法中,根据排列顺序计算每个对象的value并比较值。

const data = [
{ colors: ["Blue", "Blue", "Red"] },
{ colors: ["Blue", "Red", "White"] },
{ colors: ["Blue", "Blue", "White"] },
{ colors: ["Red", "Blue", "White"] },
{ colors: ["Red", "Blue", "Blue"] },
{ colors: ["Red", "Red", "White"] },
{ colors: ["Red", "Red", "Red"] },
];
const getValue = (obj) =>
obj.colors.reduce((acc, cur) => +(cur === "Red") + acc * 10, 0);

data.sort((a, b) => getValue(b) - getValue(a));
console.log(data);

因此,您需要在数组上循环,并确定一个是红色的,另一个是。如果两者或两者都不是,则转到下一个并进行检查。

const data = [
{ colors: ['Blue', 'Blue', 'Red'] },
{ colors: ['Blue', 'Red', 'White'] },
{ colors: ['Blue', 'Blue', 'White'] },
{ colors: ['Red', 'Blue', 'White'] },
{ colors: ['Red', 'Blue', 'Blue'] },
{ colors: ['Red', 'Red', 'White'] },
{ colors: ['Red', 'Red', 'Red'] }
];

data.sort((a,b) => {
const ac = a.colors;
const bc = b.colors
for (let i=0; i<ac.length; i++){
const check = (ac[i] === bc[i]) || (ac[i] !== 'Red' && bc[i] !== 'Red');
if (check) continue;
return ac[i] === 'Red' ? -1 : 1;
}
return 0;
});
console.log(data);

如果你必须根据其他颜色进行排序;加权值";阵列将是的一种方式

const data = [
{ colors: ['Blue', 'Blue', 'Red'] },
{ colors: ['Blue', 'Red', 'White'] },
{ colors: ['Blue', 'Blue', 'White'] },
{ colors: ['Red', 'Blue', 'White'] },
{ colors: ['Red', 'Blue', 'Blue'] },
{ colors: ['Red', 'Red', 'White'] },
{ colors: ['Red', 'Red', 'Red'] }
];
const values = {
Red: 3,
Blue: 2,
White: 1,
};
const weight = arr => +arr.map(c => values[c] || 0).reverse().join("");
data.sort((a, b) => weight(b.colors) - weight(a.colors));
console.log(data);

这里有一个可能的解决方案:

  1. 创建一个私有函数getColorScore,根据颜色及其索引的出现情况来计算colors数组的分数。这可以使用.reduce来完成
  2. 使用此函数对对象数组进行排序,其中colors列表中score较大的对象将是第一个。这是使用.sort完成的

const arr = [
{ id: 1, colors: ['Red', 'Blue', 'White'] },
{ id: 1, colors: ['Red', 'Blue', 'Blue'] },
{ id: 1, colors: ['Red', 'Red', 'White'] },
{ id: 1, colors: ['Red', 'Red', 'Red'] }
];
const getColorScore = (colors, color) => colors.reduce((acc,item,index) => {
acc += item===color ? colors.length-index : 0;
return acc;
}, 0);
const sortArrayByColor = (arr,color) =>
arr.sort((a,b) => getColorScore(b.colors,color)-getColorScore(a.colors,color))
console.log( sortArrayByColor(arr,'Red') );

最新更新