Dart:根据另一个列表过滤列表

时间:2021-02-08 20:57:44

标签: flutter dart

我有两个看起来像这样的对象:

class Field extends RESTModel {
  int id;
  String name;
  String dataType;
  int objectId;
}

class FieldKeywordMap extends RESTModel {
  int id;
  String keywordName;
  int objectConfigurationId;
  int fieldId;
}

我有一个名为 _fieldKeywordMaps 的 FieldKeywordMap 列表和一个名为 _selectedFields 的字段列表。我正在编写一个函数来返回基于 2 个条件的 _fieldKeywordMaps 的过滤版本:

  1. 其中 objectConfigurationId 等于 selectedObjectConfiguration().id
  2. 其中 fieldId 等于 _selectedFields 中项目的 id。

基于第一个条件的过滤有效,但我无法确定如何遍历我的 _selectedFields 列表并将其与 _fieldKeywordMaps 中的对象进行比较。代码如下:

    selectObjectKeywordMaps() async {
    if (selectedObjectConfiguration() != null && selectedObject() != null) {
      List<FieldKeywordMap> _maps = _fieldKeywordMaps
          .where((keywordMap) =>
              keywordMap.objectConfigurationId == selectedObjectConfiguration().id)
          .where((filteredKeywordMap) =>
              _selectedFields.map((field) => field.id).contains(filteredKeywordMap.id))
          .toList();
      _selectedObjectKeywordMaps = _maps.toList();
      fetchAffectedCustomers();
    } else {
      _selectedObjectKeywordMaps = [];
    }
    notifyListeners();
  }

1 个答案:

答案 0 :(得分:1)

.where((filteredKeywordMap) => _selectedFields.map(...)) 不合适。 Iterable.map 用于执行从一个 Iterable 到另一个 .where((filteredKeywordMap) => _selectedFields.any((field) => field.id == filteredKeywordMap.fieldId)) 的 1:1 转换。

你可以这样做:

_selectedFields

请注意,这可能效率低下;使 Mapids 到 Fields 而不是 List<Field>s 的 class MainSection extends Component { state = { data: null, filteredData: null, loading: true, filterLanguages: null, slideText: false, currentFilter: 'All' } async componentDidMount() { try { // eslint-disable-next-line no-unused-vars const resp = await axios .get("https://backendkham.herokuapp.com/api/show") .then((response) => { const finalLangs = ["All"]; const languages = response.data.data.forEach((element) => { element.repos.forEach((repo) => { // console.log(repo.languages) finalLangs.push(repo.languages); }); }); const validData = response.data.data.filter( (user) => user.repos.length > 0 ); this.setState(prevState => ({ ...prevState, data: [...validData], filteredData: [...validData], loading: false, filterLanguages: [...new Set(finalLangs)].filter((item) => item) })) }); } catch (error) { console.log(error); return Promise.reject(error); } } render() { const filterRepos = (lang) => { // console.log(lang) if (lang === "All") { this.setState(prevState => ({ filteredData: prevState.data })) } else { const dataToBeFiltered = [...this.state.data].map((obj) => { // console.log(obj.repos); obj.repos = obj.repos.filter((repo) => repo.languages === lang); // console.log(obj.repos); return obj; }); this.setState(prevState => ({ ...prevState, filteredData: dataToBeFiltered })) console.table(this.state); // console.log(filteredData); // console.log(dataToBeFiltered); } }; const newFilter = (repoLang) => { this.setState(prevState => ({ ...prevState, currentFilter: repoLang })) } const animateFilterOptions = () => { this.setState(prevState => ({ ...prevState, slideText: !prevState.slideText })) } if (this.state.loading) { return ( <Loader className={classes.Loader} type="TailSpin" color="#00BFFF" height={100} width={100} //3 secs /> ); } if (this.state.data) { // console.log('filter languages are:', typeof(filterLanguages[0])); // console.log('data in render method:', data) return ( <> <Filter filterRepos={(event) => filterRepos(event.target.value)} slideText={this.state.slideText} btnClick={animateFilterOptions} languages={this.state.filterLanguages} /> <div className={classes.Main}> <Cards data={this.state.filteredData} /> </div> </> ); } } }; 将使查找更快更简单。

相关问题