在 Spotify 播放列表应用程序中添加和删除曲目
Adding and removing tracks from a Spotify playlist app
我目前正在完成一个项目,我必须在其中构建一个 Spotify 播放列表创建器。为此,我需要在播放列表中添加或删除曲目。我编写了一个看起来可行的方法,但它与官方解决方案不同,所以我只是想看看是否有理由不按我的方式去做。
具体来说,他们在我使用 .includes 的地方使用 .find 和 .filter 方法。我所做的有缺点吗?
他们的代码
addTrack(track) {
let tracks = this.state.playlistTracks;
if (tracks.find(savedTrack => savedTrack.id === track.id)) {
return;
}
tracks.push(track);
this.setState({ playlistTracks: tracks});
}
removeTrack(track) {
let tracks = this.state.playlistTracks;
tracks = tracks.filter(currentTrack => currentTrack.id !== track.id);
this.setState({playlistTracks: tracks});
}
我的代码
addTrack(track) {
let tracks = this.state.playlistTracks;
if (!tracks.includes(track)) {
tracks.push(track);
}
this.setState({playlistTracks: tracks});
}
removeTrack(track) {
let tracks = this.state.playlistTracks;
if (tracks.includes(track)) {
let index = tracks.indexOf(track);
tracks.splice(index, 1);
}
this.setState({playlistTracks: tracks});
}
问题与引用有关,您已对 playlistTracks
进行了另一个引用
addTrack(track) {
let { playlistTracks } = this.state;
let tracks = [...playlistTracks];
if (!tracks.includes(track)) {
tracks.push(track);
}
this.setState({ playlistTracks: tracks });
}
removeTrack(track) {
let { playlistTracks } = this.state;
let tracks = [...playlistTracks];
if (tracks.includes(track)) {
let index = tracks.indexOf(track);
tracks.splice(index, 1);
}
this.setState({ playlistTracks: tracks });
}
我的建议
addTrack(track) {
const { playlistTracks } = this.state;
const tracks = [...playlistTracks];
const index = tracks.indexOf(track);
if (index < 0) {
tracks.push(track);
}
this.setState({ playlistTracks: tracks });
}
removeTrack(track) {
const { playlistTracks } = this.state;
const tracks = [...playlistTracks];
const index = tracks.indexOf(track);
if (index > -1) {
tracks.splice(index, 1);
}
this.setState({ playlistTracks: tracks });
}
是的,有一个显着的区别,因为 includes()
只会 return true
如果你传递给它实际的实例(我的意思是指向相同的引用对象)您正在寻找的曲目。
所提供的解决方案仅根据曲目 ID 比较曲目,因此有所不同。
参见以下示例:
const tracks = [
{id: 1, title: "mysong1"},
{id: 2, title: "mysong2"},
]
function isTrackPresentIncludes(track){
return tracks.includes(track);
}
function isTrackPresentFind(track){
return tracks.find(it => it.id === track.id) !== undefined;
}
// this will be true
console.log("with includes(tracks[0]):\n", isTrackPresentIncludes(tracks[0]))
// this will be false as it's a different object
console.log("with includes({id: 1, title: \"mysong1\"}):\n", isTrackPresentIncludes({id: 1, title: "mysong1"}))
// this will be true
console.log("with find(tracks[0]):\n", isTrackPresentFind(tracks[0]))
// this will also be true
console.log("with find({id: 1, title: \"mysong1\"}):\n", isTrackPresentFind({id: 1, title: "mysong1"}))
您的 removeTrack()
中的 indexOf()
也有同样的问题。
还有一点我不太喜欢这个解决方案。 find()
returns 找到的曲目,但 return 值从未实际使用过,所以在我看来你应该使用 some()
而不是 returns true
或 false
.
我认为这不是问题,但如果数组包含 falsy 值,它可能会导致意外行为。
考虑一下:
const arrayWithFalsyValues = [
0, // zero is falsy!
1,
2,
3,
4,
5,
6,
7,
8
]
function isPresent(toBeFound){
if(arrayWithFalsyValues.find(number => number === toBeFound)){
console.log(`Value ${toBeFound} found in array`);
}
else{
console.log(`Value ${toBeFound} NOT found in array`);
}
}
console.log("Array:", arrayWithFalsyValues)
// this will work as expected
console.log("Contains 3?")
isPresent(3)
console.log("Contains 8?")
isPresent(8)
console.log("Contains 10?")
isPresent(10)
// now search for the falsy value -> incorrect result
console.log("Contains 0?")
isPresent(0)
我目前正在完成一个项目,我必须在其中构建一个 Spotify 播放列表创建器。为此,我需要在播放列表中添加或删除曲目。我编写了一个看起来可行的方法,但它与官方解决方案不同,所以我只是想看看是否有理由不按我的方式去做。
具体来说,他们在我使用 .includes 的地方使用 .find 和 .filter 方法。我所做的有缺点吗?
他们的代码
addTrack(track) {
let tracks = this.state.playlistTracks;
if (tracks.find(savedTrack => savedTrack.id === track.id)) {
return;
}
tracks.push(track);
this.setState({ playlistTracks: tracks});
}
removeTrack(track) {
let tracks = this.state.playlistTracks;
tracks = tracks.filter(currentTrack => currentTrack.id !== track.id);
this.setState({playlistTracks: tracks});
}
我的代码
addTrack(track) {
let tracks = this.state.playlistTracks;
if (!tracks.includes(track)) {
tracks.push(track);
}
this.setState({playlistTracks: tracks});
}
removeTrack(track) {
let tracks = this.state.playlistTracks;
if (tracks.includes(track)) {
let index = tracks.indexOf(track);
tracks.splice(index, 1);
}
this.setState({playlistTracks: tracks});
}
问题与引用有关,您已对 playlistTracks
addTrack(track) {
let { playlistTracks } = this.state;
let tracks = [...playlistTracks];
if (!tracks.includes(track)) {
tracks.push(track);
}
this.setState({ playlistTracks: tracks });
}
removeTrack(track) {
let { playlistTracks } = this.state;
let tracks = [...playlistTracks];
if (tracks.includes(track)) {
let index = tracks.indexOf(track);
tracks.splice(index, 1);
}
this.setState({ playlistTracks: tracks });
}
我的建议
addTrack(track) {
const { playlistTracks } = this.state;
const tracks = [...playlistTracks];
const index = tracks.indexOf(track);
if (index < 0) {
tracks.push(track);
}
this.setState({ playlistTracks: tracks });
}
removeTrack(track) {
const { playlistTracks } = this.state;
const tracks = [...playlistTracks];
const index = tracks.indexOf(track);
if (index > -1) {
tracks.splice(index, 1);
}
this.setState({ playlistTracks: tracks });
}
是的,有一个显着的区别,因为 includes()
只会 return true
如果你传递给它实际的实例(我的意思是指向相同的引用对象)您正在寻找的曲目。
所提供的解决方案仅根据曲目 ID 比较曲目,因此有所不同。
参见以下示例:
const tracks = [
{id: 1, title: "mysong1"},
{id: 2, title: "mysong2"},
]
function isTrackPresentIncludes(track){
return tracks.includes(track);
}
function isTrackPresentFind(track){
return tracks.find(it => it.id === track.id) !== undefined;
}
// this will be true
console.log("with includes(tracks[0]):\n", isTrackPresentIncludes(tracks[0]))
// this will be false as it's a different object
console.log("with includes({id: 1, title: \"mysong1\"}):\n", isTrackPresentIncludes({id: 1, title: "mysong1"}))
// this will be true
console.log("with find(tracks[0]):\n", isTrackPresentFind(tracks[0]))
// this will also be true
console.log("with find({id: 1, title: \"mysong1\"}):\n", isTrackPresentFind({id: 1, title: "mysong1"}))
您的 removeTrack()
中的 indexOf()
也有同样的问题。
还有一点我不太喜欢这个解决方案。 find()
returns 找到的曲目,但 return 值从未实际使用过,所以在我看来你应该使用 some()
而不是 returns true
或 false
.
我认为这不是问题,但如果数组包含 falsy 值,它可能会导致意外行为。 考虑一下:
const arrayWithFalsyValues = [
0, // zero is falsy!
1,
2,
3,
4,
5,
6,
7,
8
]
function isPresent(toBeFound){
if(arrayWithFalsyValues.find(number => number === toBeFound)){
console.log(`Value ${toBeFound} found in array`);
}
else{
console.log(`Value ${toBeFound} NOT found in array`);
}
}
console.log("Array:", arrayWithFalsyValues)
// this will work as expected
console.log("Contains 3?")
isPresent(3)
console.log("Contains 8?")
isPresent(8)
console.log("Contains 10?")
isPresent(10)
// now search for the falsy value -> incorrect result
console.log("Contains 0?")
isPresent(0)