【问题标题】:Sort an array of objects against an array of params with a matching value根据具有匹配值的参数数组对对象数组进行排序
【发布时间】:2021-06-05 18:20:34
【问题描述】:

上下文:我有一个多选下拉菜单。用户选择多个对象值。在每个对象中都有一个我想要匹配的字符串值。每个多选都有分配的参数。这些参数稍后用于将选择整理到自己的数组中以发送回 api。

问题:我尝试循环选择并匹配参数。在我的情况下,选择和参数只有在它们碰巧同时在同一个循环中时才会匹配,换句话说,改变参数的顺序会改变结果。

我创建了一个stackblitz,它代表已被使用的相同数据和逻辑模型。在演示中没有下拉菜单,我通过添加一个按钮来模拟响应,以触发已经提供模拟数据的函数。您将看到我通过 console.logs() 获得的输出

预期行为

选择

  mockSelections = [
    {
      id: "4",
      type: "I_am_BLUE"
    },
    {
      id: "1",
      type: "I_am_RED"
    },
    {
      id: "2",
      type: "I_am_GREEN"
    },
    {
      id: "3",
      type: "I_am_BLUE"
    }
  ];

期望的输出

  this.filterState = {
      I_am_RED: [
        {
          id: "1",
          type: "I_am_RED"
        }
      ],
      I_am_GREEN: [
        {
          id: "2",
          type: "I_am_GREEN"
        }
      ],
      I_am_BLUE: [
        {
          id: "3",
          type: "I_am_BLUE"
        },
        {
          id: "4",
          type: "I_am_BLUE"
        }
      ]
  };

所以基本上,所需的输出会将所有带有“I_am_BLUE”的选择放在“I_am_BLUE”数组中,与绿色和绿色、红色和红色相同

功能

  handleFilterChange(prop: string, value: any): void {
    let field = this.fields.find(f => f.name === prop);

    if (field.params) {
      console.log("FIELD PARAMS", field.params);
      console.log("SELECTED VALUES", value);
      field.params.forEach((param, i) => {
        // some sort of double looping logic needed here?
        if (value[i].type === param) {
          this.setFilterState(param, value[i], field);
        }
      });
    } else {
      this.setFilterState(prop, value, field);
    }
    console.log("SUBMITTED SORTED VALUES", this.filterState);
  }

StackBlitz example - https://stackblitz.com/edit/ngx-select-dropdown-acntzk?file=app%2Fapp.component.ts

【问题讨论】:

  • 如果您可以发布您的 HTML 的完整代码,将会很有用。可能不是您的选择代码,而是您侦听更改的方式。
  • 嘿。不,HTML 不会对结果产生影响。我几乎没有在演示中添加任何 HTML,而是直接从 ngoni() 运行它。该方法获得的响应与从选择中获得的响应相同
  • 我忘了说上面的输出是想要的输出。
  • 奇怪。首先,您告诉我们您希望 this.setFilterState 成为具有 I_am_RED 键、...等的对象,然后显示 this.setFilterStatefunction 的代码。不知道你想要什么。什么是this.setFilterState
  • 好地方。是的,我有一个名为 this.filterState 的对象和一个名为 setFilterState 的函数

标签: javascript angular typescript sorting filter


【解决方案1】:

尝试这些更改:

  handleFilterChange(prop: string, value: any): void {
    let field = this.fields.find(f => f.name === prop);
    for (const [key, value] of Object.entries(this.filterState))
      value.splice(0);
    if (field.params) {
      console.log("FIELD PARAMS", field.params);
      console.log("SELECTED VALUES", value);
      value.forEach(v => this.setFilterState(v.type, v, field));
    } else {
      this.setFilterState(prop, value, field);
    }
    console.log("SUBMITTED SORTED VALUES", this.filterState);
  }

  setFilterState(prop: string, value: any, field: Field): void {
    if (field.name === "multiselect_1") {
      this.filterState[prop].push(value);
    } else {
      //There will be more logic here
      this.filterState[prop] = value;
    }
  }

【讨论】: