【问题标题】:Filtering an array of objects based on their ID attribute根据 ID 属性过滤对象数组
【发布时间】:2015-09-10 15:47:40
【问题描述】:

使用 iTunes 的搜索 API 我希望根据特定条件从专辑中获取歌曲集合。在这个solution 的帮助下,我设法完成了一半。唯一的问题是,有时专辑可能是干净的或明确的,最终会输出重复的歌曲。

我认为在这种情况下最好的解决方案是根据他们的collectionId 获取第一个可用的(有时是唯一的)歌曲集。不幸的是,这个值不像我在 filter() 函数中传递的值那样被临时知道。

如何利用下面的代码干净地选择一组:

$(function() {
  iTunesSearch("Beauty Behind the Madness", "The Weeknd");

  function iTunesSearch(album, artist, callback) {
    var results;

    $.getJSON("http://itunes.apple.com/search?term=" + album + "&entity=song&callback=?", function(data) {
      results = data["results"];
      console.log( filter(results, { collectionName: album, artistName: artist }) );
    });
  }

  function filter(arr, criteria) {
    return arr.filter(function(obj) {
      return Object.keys(criteria).every(function(c) {
        return obj[c] == criteria[c];
      });
    });
  }   
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

【问题讨论】:

    标签: javascript jquery ajax filter itunes


    【解决方案1】:

    此过滤器功能按照您的要求执行,即它抓取第一个曲目集合

    function filter(arr, criteria) {
        var tracks = arr.filter(function(track) {
            return Object.keys(criteria).every(function(c) {
                return track[c] == criteria[c];
            });
        });
        if (!tracks.length) {
            return [];
        }
        return tracks.filter(function(track) {
            return track.collectionId == tracks[0].collectionId;
        });
    }
    

    编辑:

    这里有一个优化以避免两次过滤器通过,但它使它有点难以阅读:

    function filter(arr, criteria) {
        var firstCollectionId = null;
        return arr.filter(function(track) {
            var isMatch = Object.keys(criteria).every(function(c) {
                return track[c] == criteria[c];
            });
            if (isMatch) {
                if (firstCollectionId === null) {
                    firstCollectionId = track.collectionId;
                    return true;
                }
                return track.collectionId === firstCollectionId;
            }
            return false;
        });
    }
    

    【讨论】:

    • 您认为使用此解决方案,try/catch 会有助于您检查过滤后的曲目是否为空?我正在考虑与您的解决方案类似的解决方案,但无法得出合理的结论。
    • 如果没有匹配的曲目,if(!tracks.length){return [];} 将返回一个空数组。我认为没有必要尝试/捕获。
    • 我明白了。一个额外的问题。您为什么决定不将返回值包装在条件的 else 块中?我指的是调用filter() 方法的第二个实例。
    • 个人风格。如果我可以避免它,我宁愿不要有 else 块,因为另一个缩进和更多的花括号对人眼来说更难解析
    • 太棒了。非常感谢你的帮助。对于您的第二个解决方案,虽然我得到了错误:Uncaught TypeError: Cannot read property '0' of undefined
    【解决方案2】:

    这是一种解决方法:)

    $(function() {
      iTunesSearch("Beauty Behind the Madness", "The Weeknd");
    
      function iTunesSearch(album, artist, callback) {
        var results;
    
        $.getJSON("http://itunes.apple.com/search?term=" + album + "&entity=song&callback=?", function(data) {
          results = data["results"];
          console.log( filter(results, { collectionName: album, artistName: artist }, 'collectionId') );
        });
      }
    
      function filter(arr, criteria, key) {
        var keys = [];
        return arr.filter(function(obj) {
          var keyVal = obj[key];
          var result = Object.keys(criteria).every(function(c) {
            return obj[c] == criteria[c];
          }) && !keys.includes(keyVal);
          if(keyVal) keys.push(keyVal);
          return result;
        });
      }   
    });

    【讨论】:

      【解决方案3】:

      我相信我了解您需要什么...拥有来自特定专辑的一系列独特歌曲。如果这是正确的,这里有一个解决方案:

      $(function() {
      
          iTunesSearch("Beauty+Behind+the+Madness", "The+Weeknd");
      
          function iTunesSearch(album, artist, callback) {
              var results,
                  tracks = [];
      
              $.getJSON("http://itunes.apple.com/search?term=" + album + "&media=music&entity=song&callback=?", function(data) {
                  data.results.map(function (album) {
                      if (tracks.indexOf(album.trackName) === -1) {
                          tracks.push(album.trackName);
                      }
                  });
                  console.log(tracks);
              });
          }
      
      });
      

      http://jsfiddle.net/4vj05v7c/

      我选择仅使用曲目名称填充数组,以便更容易看到不包含重复项。

      【讨论】:

        猜你喜欢
        • 2018-12-25
        • 2018-07-06
        • 2016-05-15
        • 2021-04-15
        • 2017-03-19
        • 2018-09-27
        相关资源
        最近更新 更多