[英]Sort array four times with different weighting in typescript
I want to sort an array four times, each time the sort-array-button is pressed a different status should be on top.我想对数组进行四次排序,每次按下排序数组按钮时,不同的状态应该在顶部。
0: {id: 1, status: "danger"}
1: {id: 2, status: "danger"}
3: {id: 3, status: "red"}
4: {id: 4, status: "red"}
5: {id: 5, status: "yellow"}
6: {id: 6, status: "yellow"}
7: {id: 7, status: "green"}
First click on the sort button: danger, danger, red, red, yellow, yellow, green
second press: red, red, yellow, yellow, green, danger, danger
third press: yellow, yellow, green, danger, danger, red, red
fourth press: green, danger, danger, red, red, yellow, yellow
and with the fifth press you are back to the first sort again danger, danger, red, red, yellow, yellow, green
第一次点击排序按钮:
danger, danger, red, red, yellow, yellow, green
第二次按下: red, red, yellow, yellow, green, danger, danger
第三次按下: yellow, yellow, green, danger, danger, red, red
第四次按: green, danger, danger, red, red, yellow, yellow
,第五次按您又回到第一次danger, danger, red, red, yellow, yellow, green
Normally I sort arrays like this:通常我像这样对 arrays 进行排序:
myArray.sort((x, y) => x.status < y.status ? -1 : 1);
How can I extend the sort to give a color a higher value to make this work again?如何扩展排序以赋予颜色更高的值以使其再次起作用?
Normally I sort arrays like this
通常我像这样排序 arrays
First we have to fix that.首先我们必须解决这个问题。 :-) You need to return
0
when x.status
and y.status
are the same. :-) 当
x.status
和y.status
相同时,您需要返回0
。 In general, for strings it's (x, y) => x.status.localeCompare(y.status)
and for numbers it's (x, y) => x.status - y.status
(reverse x
and y
to switch from ascending to descending).一般来说,对于字符串它是
(x, y) => x.status.localeCompare(y.status)
而对于数字它是(x, y) => x.status - y.status
(反转x
和y
从升序切换下降)。
In your case, you want to assign values to the status
types, and those values differ based on the click (apparently).在您的情况下,您希望为
status
类型分配值,并且这些值根据点击而有所不同(显然)。 To do that, give yourself mappings of status->number that you can pick based on what click it is:为此,请给自己映射 status->number ,您可以根据点击次数来选择:
const sortStyles = [
{
danger: 0,
red: 1,
yellow: 2,
green: 3,
},
{
red: 0,
yellow: 1,
green: 2,
danger: 3,
},
{
yellow: 0,
green: 1,
danger: 2,
red: 3,
},
{
green: 0,
danger: 1,
red: 2,
yellow: 3,
}
];
Then the sort is:那么排序是:
const style = sortStyles[index]; // index = 0 for first click, 1 for second, etc.
data.sort((x, y) => style[x.status] - style[y.status]));
Live Example:现场示例:
const data = [ {id: 1, status: "danger"}, {id: 2, status: "danger"}, {id: 3, status: "red"}, {id: 4, status: "red"}, {id: 5, status: "yellow"}, {id: 6, status: "yellow"}, {id: 7, status: "green"} ]; const sortStyles = [ { danger: 0, red: 1, yellow: 2, green: 3, }, { red: 0, yellow: 1, green: 2, danger: 3, }, { yellow: 0, green: 1, danger: 2, red: 3, }, { green: 0, danger: 1, red: 2, yellow: 3, } ]; example("First click, sortStyles[0]:", data, sortStyles[0]); example("Second click, sortStyles[1]:", data, sortStyles[1]); example("Third click, sortStyles[2]:", data, sortStyles[2]); example("Fourth click, sortStyles[3]:", data, sortStyles[3]); function example(label, data, style) { console.log(label); console.log(data.slice().sort((x, y) => style[x.status] - style[y.status])); }
Conceptually (and not paying much attention to performance), you need to define an order for your status
properties, and then rotate that order.从概念上讲(并且不太关注性能),您需要为您的
status
属性定义一个顺序,然后轮换该顺序。 You could do it like this:你可以这样做:
let order = ["danger", "red", "yellow", "green"];
function click() {
order.push(order.shift()!)
myArray.sort((x, y) => order.indexOf(x.status) - order.indexOf(y.status))
}
So when you call click()
, the order
array will take the first element off the list and push it onto the end.因此,当您调用
click()
时, order
数组将从列表中取出第一个元素并将其推送到末尾。 And then you sort myArray
based on the location of its status
property in order
(and if you are missing a status in order
you can expect those to appear at the very front of the list no matter what; not sure what you want to do about edge cases like this, but you can handle them).然后根据其
status
属性的位置按order
对myArray
进行排序(如果您按order
缺少状态,则无论如何都可以期望这些状态出现在列表的最前面;不确定您要做什么像这样的边缘情况,但你可以处理它们)。
This gives the following behavior for this code:这为此代码提供了以下行为:
function show() {
console.log(myArray.map(x => x.status).join(", "))
}
show();
for (let x = 0; x < 10; x++) {
console.log("CLICK");
click();
show();
}
Console log:控制台日志:
danger, danger, red, red, yellow, yellow, green
CLICK
red, red, yellow, yellow, green, danger, danger
CLICK
yellow, yellow, green, danger, danger, red, red
CLICK
green, danger, danger, red, red, yellow, yellow
CLICK
danger, danger, red, red, yellow, yellow, green
CLICK
red, red, yellow, yellow, green, danger, danger
CLICK
yellow, yellow, green, danger, danger, red, red
CLICK
green, danger, danger, red, red, yellow, yellow
CLICK
danger, danger, red, red, yellow, yellow, green
CLICK
red, red, yellow, yellow, green, danger, danger
CLICK
yellow, yellow, green, danger, danger, red, red
Looks like what you want.看起来像你想要的。 Hope that helps;
希望有帮助; good luck!
祝你好运!
Thank you all for your help.谢谢大家的帮助。 This is the working solution I'm using now.
这是我现在正在使用的工作解决方案。
let sortStyle = {};
switch (this.sortStatus) {
case ('none'):
sortStyle = {alert: 0, red: 1, yellow: 2, green: 3};
this.myArray.sort((x, y) => sortStyle[x.status] - sortStyle[y.status]);
this.sortStatus= 'alert';
break;
case ('alert'):
sortStyle = {red: 0, yellow: 1, green: 2, alert: 3};
this.myArray.sort((x, y) => sortStyle[x.status] - sortStyle[y.status]);
this.myArray= 'red';
break;
case ('red'):
sortStyle = {yellow: 0, green: 1, alert: 2, red: 3};
this.myArray.sort((x, y) => sortStyle[x.status] - sortStyle[y.status]);
this.sortStatus = 'yellow';
break;
case ('yellow'):
sortStyle = {green: 0, alert: 1, red: 2, yellow: 3};
this.myArray.sort((x, y) => sortStyle[x.status] - sortStyle[y.status]);
this.sortStatus= 'green';
break;
case ('green'):
sortStyle = {alert: 0, red: 1, yellow: 2, green: 3};
this.myArray.sort((x, y) => sortStyle[x.status] - sortStyle[y.status]);
this.sortStatus= 'alert';
break;
default:
console.log('Error');
break;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.