【问题标题】:Filtering a particular value in an array inside a key value pair过滤键值对内数组中的特定值
【发布时间】:2019-01-25 06:40:16
【问题描述】:

从给定的对象中,我需要根据用户输入过滤掉城市。

我有一个对象:

arr= [
    {'country':'india','cities':['bangalore','chennai']},
    { 'country': 'USA' , 'cities': ['New yourk','Chicago'] }
  ]

默认情况下,它将在 html 中显示每个国家和值。当用户在输入中键入一个值时,我只需要显示与输入匹配的“城市”。

这是链接:
https://stackblitz.com/edit/angular-pxaa7b?file=src%2Fapp%2Fapp.component.ts

当有人开始输入内容时,我需要显示与用户输入匹配的城市结果。

【问题讨论】:

  • 如果我开始输入 I,那么所有城市都以 I 开头/具有 I。用首字母或中间字母过滤不是问题,我会处理,问题是使用 map() 和 filter()返回数组内未显示在 html 中的数组

标签: javascript ecmascript-6


【解决方案1】:

我应该检查你的堆栈闪电战,在你的特殊情况下:

res=this.arr.map(e=>({...e, cities: e.cities.filter(city => city.toLowerCase().indexOf(val.toLowerCase()) > -1)}))

【讨论】:

  • 它确实返回了值,但国家属性不必要地显示。我可以只显示城市而不显示其他任何内容吗
  • 其实我明白了。删除了扩展运算符,它按要求工作
【解决方案2】:
filteredArray = input.valueChanges.pipe(
 map(inputValue => arr.filter(arrValue => arrValue.startsWith(inputValue)))
);

并在过滤数组上使用异步管道。

【讨论】:

  • 似乎是完美的答案,如果您将此逻辑放入某种自定义管道会更好:)
  • 使用输入值的管道将是不纯的管道,我建议不要这样做。
  • 获取错误“属性 'valueChanges' 在类型 '{ 'country': string; 'cities': string[]; }[]' 上不存在。”
【解决方案3】:

试试这个:

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  display = [];
  arr = [
    { 'country': 'india', 'cities': ['Bangalore', 'Chennai'] },
    { 'country': 'USA', 'cities': ['New York', 'Chicago'] }
  ]
  name = 'Angular';
  constructor() {
    this.display = this.arr;
  }


  search(e) {
    let input = e.target.value.toLowerCase();
    // this.display = input ? this.filter(input) : this.arr;
    this.display = input ? this.filterByArrayMethods(input) : this.arr;
  }

  filter(val) {
    let res = [];
    this.arr.forEach(countryObj => {
      const countryToAdd = {
        country: countryObj.country,
        cities: countryObj.cities.filter(city => city.toLowerCase().includes(val))
      };
      if(countryToAdd.cities.length > 0) {
        res.push(countryToAdd);
      }
    });
    return res
  }

  filterByArrayMethods(val) {
    return this.arr.reduce((accumulator, countryObject) => {
      const citiesInTheCountry = countryObject.cities.filter(cityName => cityName.toLowerCase().includes(val));
      if (citiesInTheCountry.length > 0) accumulator.push({ ...countryObject, cities: citiesInTheCountry })
      return accumulator;
    }, []);
  }


}

这里有一个Working Sample StackBlitz 供您参考。

【讨论】:

  • 我更喜欢使用 filter()、map() 或 reduce() 来寻找一个简短的解决方案。
  • 你的函数“filterByArrayMethods()”是我正在寻找的一种解决方案,它使用 map() 和 filter() 的链接。可以实现吗?
  • @UdG 我已经用reduce 更新了我的答案和 StackBlitz,如果这就是你要找的。​​span>
  • 我接受了上面的一个,因为它满足了我的要求。但是您的答案也值得一看,我会保留它作为其他用例的参考。谢谢
猜你喜欢
  • 2022-07-12
  • 1970-01-01
  • 2020-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 2020-08-28
  • 1970-01-01
相关资源
最近更新 更多