根据 ID 属性过滤对象数组

Filtering an array of objects based on their ID attribute

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

我认为在这种情况下,最好的解决方案是获取 第一个可用的(有时仅)基于 collectionId 的歌曲集。不幸的是,这个值并不像我在 filter() 函数中传递的值那样随手可知。

我怎样才能干净利落地 select 只有一组利用下面的代码:

$(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>

这里有一个解决方法:)

$(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;
    });
  }   
});

我相信我明白您需要什么...从特定专辑中获得一系列独特的歌曲。如果这是正确的,这里有一个解决方案:

$(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/

我选择只用曲目名称填充数组,这样可以更容易地看到不包括重复项。

这个过滤函数完成了你的要求,即它抓取了第一个曲目集合

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;
    });
}