【问题标题】:Sort array four times with different weighting in typescript在打字稿中以不同的权重对数组进行四次排序
【发布时间】:2020-08-31 03:03:46
【问题描述】:

我想对一个数组进行四次排序,每次按下 sort-array-button 时,不同的状态应该在顶部。

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"}

首先点击排序按钮: 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

我通常这样对数组进行排序:

myArray.sort((x, y) => x.status < y.status ? -1 : 1);

如何扩展排序以赋予颜色更高的值以使其再次起作用?

【问题讨论】:

  • 你应该在你的json中添加priority属性
  • “我通常这样对数组进行排序” 这是不正确的。当x.statusy.status 相同时,您需要返回0。对于字符串:(x, y) =&gt; x.status.localeCompare(y.status)。对于数字:(x, y) =&gt; x.status - y.status.
  • @Aman Kumayu 我无法编辑 json。
  • @T.J.克劳德很高兴知道!我会更新我的代码。对这个问题还有什么想法吗?

标签: arrays typescript sorting


【解决方案1】:

通常我会像这样对数组进行排序

首先我们必须解决这个问题。 :-) 当x.statusy.status 相同时,您需要返回0。一般来说,字符串是(x, y) =&gt; x.status.localeCompare(y.status),数字是(x, y) =&gt; x.status - y.status(反向xy,从升序切换到降序)。

在您的情况下,您希望将值分配给 status 类型,并且这些值会因点击而有所不同(显然)。为此,请给自己映射 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,
    }
];

那么排序是:

const style = sortStyles[index]; // index = 0 for first click, 1 for second, etc.
data.sort((x, y) => style[x.status] - style[y.status]));

现场示例:

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]));
}

【讨论】:

  • 正是我需要的!非常感谢你的帮助!而且我再也不会使用那种糟糕的排序了;)
  • @JanBürger - 你离第一个犯这个错误的人很远。 :-) 很高兴有帮助!
【解决方案2】:

从概念上讲(并不太关注性能),您需要为 status 属性定义一个顺序,然后轮换该顺序。你可以这样做:

let order = ["danger", "red", "yellow", "green"];

function click() {
  order.push(order.shift()!)
  myArray.sort((x, y) => order.indexOf(x.status) - order.indexOf(y.status))
}

所以当您调用click() 时,order 数组将从列表中取出第一个元素并将其推到末尾。然后您根据orderstatus 属性的位置对myArray 进行排序(如果您缺少order 中的状态,则无论如何都可以期望这些状态出现在列表的最前面;不确定你想对这样的边缘情况做什么,但你可以处理它们)。

这给出了此代码的以下行为:

function show() {
  console.log(myArray.map(x => x.status).join(", "))
}

show();
for (let x = 0; x < 10; x++) {
  console.log("CLICK");
  click();
  show();
}

控制台日志:

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

看起来像你想要的。希望有帮助;祝你好运!

Playground link to code

【讨论】:

    【解决方案3】:

    感谢大家的帮助。这是我现在使用的有效解决方案。

    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;
        }
      }
    

    【讨论】:

      猜你喜欢
      • 2022-11-25
      • 2017-03-19
      • 2018-10-09
      • 1970-01-01
      • 2020-10-01
      • 1970-01-01
      • 2021-03-02
      • 2021-10-23
      • 2017-02-12
      相关资源
      最近更新 更多