【问题标题】:Typescript - Check values in one array are present in anotherTypescript - 检查一个数组中的值是否存在于另一个数组中
【发布时间】:2020-06-09 06:58:15
【问题描述】:

我有以下数组。我正在使用这个数组在我的 UI 上动态生成复选框。这用于保存用户配置,以了解他们将能够在导航菜单中看到的内容。

  accessLevels: any = [
    {
      description: "Properties",
      type: '1',
      selected: false
    },
    {
      description: "Equipment",
      type: '2',
      selected: false
    },
    {
      description: "Jobs",
      type: '3',
      selected: false
    },
    {
      description: "Calender",
      type: '4',
      selected: false
    }
]

我正在调用一个 API,它返回一个用户配置数组。所以我将得到一个页面数组及其类型,如下所示:

    {
      description: "Equipment",
      type: '2'
    },
    {
      description: "Jobs",
      type: '3'
    }

在从 API 返回的数组中,我只是得到应该出现在复选框上的值,所以我想要做的是遍历返回的数组并检查是否有任何类型与复选框数组中的任何类型匹配如果他们这样做,我想将'selected'设置为true。从而检查复选框。

这是我目前所拥有的:


  async loadLandlordConfig(key: string) {

    const result = await this.userService.loadLandlordConfig(key);

    //let accessLevels = [];

    this.selectedApiValues = result[0].accessLevels;

    this.selectedApiValues.forEach((selectedValue)=> {

    });
  }

我不确定如何交叉检查这些值,然后将 selected 更改为 true。

希望我已经把一切都说清楚了。 有任何问题请提出。感谢所有帮助。

【问题讨论】:

  • 如何跨数组匹配对象?一些数组项有“值”,一些有“类型”。
  • @KurtHamilton 抱歉,我只是将数组输入到那里并错过了,我的错误。我做了相应的调整
  • 所以你在匹配类型?
  • 是的,没错。

标签: arrays angular typescript checkbox


【解决方案1】:

您可以通过以下简单示例实现您想要的:

let accessLevels = [
    {
      description: "Properties",
      type: '1',
      selected: false
    },
    {
      description: "Equipment",
      type: '2',
      selected: false
    },
    {
      description: "Jobs",
      type: '3',
      selected: false
    },
    {
      description: "Calender",
      value: '4',
      selected: false
    }
]

let api = [
    {
      description: "Equipment",
      type: '2'
    },
    {
      description: "Jobs",
      value: '3'
    }
];

for(var i = 0; i < accessLevels.length; i++) {
     accessLevels[i].selected = api.find(e => e.description === accessLevels[i].description) ? true : false;
}

console.log(accessLevels);

【讨论】:

  • 您是否有理由使用 for 而不是 .forEach 进行迭代?在我看来,.find 看起来更可取,因为据我所知,它会停止并在获得值后立即返回。
  • 感谢您的注意,我更新了我的答案,但请记住,只要您能解决手头的问题,for 循环比 forEach 快。先解决,后重构!
【解决方案2】:
  const accessLevels: any[] = [
    {
      description: 'Properties',
      type: '1',
      selected: false
    },
    {
      description: 'Equipment',
      type: '2',
      selected: false
    },
    {
      description: 'Jobs',
      type: '3',
      selected: false
    },
    {
      description: 'Calender',
      type: '4',
      selected: false
    }];

  const results: any[] = [
    {
      description: 'Equipment',
      type: '2'
    },
    {
      description: 'Jobs',
      type: '3'
    }];

  accessLevels.forEach(accessLevel => {
    accessLevel.selected = results.some(x => x.type === accessLevel.type); });

【讨论】:

    【解决方案3】:

    我对您的代码进行了一些更改。下面是它的样子:

    async loadLandlordConfig(key: string) {
    
        const result = await this.userService.loadLandlordConfig(key);
    
        // assuming there's always a result.
        // ACCESS_LEVELS is the list of your config.
        accessLevels = result[0].accessLevels;
        this.selectedApiValues = ACCESS_LEVELS.map((al: any) => {
          const selected = accessLevels.findIndex(a => a.type === al.type) > -1;
          return { ...al, selected }
        })
      }
    

    这会给你带来价值

    this.selectedApiValues = [
      {
          description: "Properties",
          type: '1',
          selected: false
        },
        {
          description: "Equipment",
          type: '2',
          selected: true
        },
        {
          description: "Jobs",
          type: '3',
          selected: true
        },
        {
          description: "Calender",
          type: '4',
          selected: false
        }
    ]
    

    【讨论】:

      【解决方案4】:

      对于小数组

      您可以使用以下方法检查过滤器中是否存在:

      const intersect = this.array1.filter(a1 => 
        this.array2.some(a2 => a1.type === a2.type));
      

      这样做的问题是您正在通过数组 2 执行多个循环。

      对于更大的数组

      要将循环保持在一个常数,您可以创建一个数组的映射,并在另一个数组的过滤器中检查:

      const map2 = new Map(this.array2.map(x => [x.type, s]));
      const intersect = this.array1.filter(a1 => 
        map.has(a1.type));
      

      这增加了一点复杂性,但对于除了最简单的情况之外的所有情况都更有效。

      【讨论】:

        【解决方案5】:

        您可以在映射第二个数组时使用Map 集合来拥有O(1)

        const unique = new Map(received.map(s => [s.description, s]));
        const result = accessLevels.map(({ description, type})=> 
            ({selected: (unique.get(description) ? true : false), type, description}))
        

        一个例子:

        let accessLevels = [
          {
            description: "Properties",
            type: '1',
            selected: false
          },
          {
            description: "Equipment",
            type: '2',
            selected: false
          },
          {
            description: "Jobs",
            type: '3',
            selected: false
          },
          {
            description: "Calender",
            type: '4',
            selected: false
          }
        ]
        
        const received = [
          {
          description: "Equipment",
          type: '2'
          },
          {
            description: "Jobs",
            value: '3'
          }
        ];
        
        const unique = new Map(received.map(s => [s.description, s]));
        const result = accessLevels.map(({ description, type})=> 
            ({selected: (unique.get(description) ? true : false), type, description}))
        console.log(result);

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-08
          • 2019-11-26
          • 1970-01-01
          相关资源
          最近更新 更多