简体   繁体   English

有没有更好的方法来循环遍历一个大数组来找到每个项目的数量?

[英]Is there a better way to loop through a large array to find the number of each item?

I have a JSON file with over 20k entries with the names of different tracks on Spotify.我有一个 JSON 文件,其中包含超过 20k 个条目,其中包含 Spotify 上不同曲目的名称。 I was trying to count the number of times each song has been played by a specific artist.我试图计算特定艺术家播放每首歌曲的次数。

function countInArray(array, what) {
    var count = 0;
    for (var i = 0; i < array.length; i++) {
        if (array[i] === what) {
            count++;
        }
    }
    nfPlays.push(count)
    return count;
}
nfSongs2 = []
nfSongs = []
nfPlays = []

for(var i = 0; i < dta.length; i++) {
  if(dta[i].artistName === "NF") {
    nfSongs.push(dta[i].trackName)
  }
}
for(var i = 0; i < dta.length; i++) {
  if(nfSongs2.indexOf(dta[i].trackName) === -1 && dta[i].artistName === "NF") {
    nfSongs2.push(dta[i].trackName)
  }
}

for(var i = 0; i < nfSongs2.length; i++) {
  console.log(`${nfSongs2[i]} has ${countInArray(nfSongs, nfSongs2[i])} plays`)

}

console.log(countInArray(nfSongs, "WHY"))

console.log(nfPlays)
console.log(nfSongs2)
console.log(nfSongs)

That's currently my code.这是目前我的代码。 Basically what it does is loop through the dta array and grab all the entries by NF (specifically the track names) which includes the duplicates, and then it does that again but this time, only grabbing unique names.基本上它所做的是遍历dta数组并通过 NF 获取所有条目(特别是曲目名称),其中包括重复项,然后再次执行此操作,但这一次,仅获取唯一名称。 Then I run countInArray on all the unique names of the tracks which will grab the number of plays and push it to the nfPlays array.然后我在countInArray的所有唯一名称上运行countInArray ,它将获取播放次数并将其推送到nfPlays数组。

Not especially complicated and it does work.不是特别复杂,它确实有效。 I was wondering if there is a better, shorter way of doing this.我想知道是否有更好,更短的方法来做到这一点。

I think you should try the filter method.我认为您应该尝试filter方法。 For example:例如:

function countInArray(array, what) {
    const foundItems = array.filter(value => value === what);
    nfPlays.push(foundItems.length)
    return foundItems.length;
}

Or或者

const foundTracks = dta.filter(track => track.artistName === "NF");

Background 背景

You can use a Map which is presents a faster lookup than an array (indexOf)您可以使用比数组 (indexOf) 更快查找的 Map

 const dta = [ { trackName:'a', artistName:'NF' }, { trackName:'a', artistName:'NF' }, { trackName:'b', artistName:'NF' }, { trackName:'b', artistName:'other' }, ] const trackNameToCount = dta.reduce((m, track) => { if (track.artistName === 'NF') { const n = m.get(track.trackName) || 0 m.set(track.trackName, n+1) } return m }, new Map()) ;[...trackNameToCount.entries()].forEach(([name, count]) => { console.log(`${name} played ${count} times`) })

Hope I understand what you're doing.希望我明白你在做什么。 I'd suggest using the object type to handle duplicates.我建议使用对象类型来处理重复项。 Something like this?像这样的东西?

 dta = [ {trackName: "dog", artistName: "NF"}, {trackName: "dog", artistName: "mack"}, {trackName: "dog", artistName: "NF"}, {trackName: "cat", artistName: "fred"}, {trackName: "mouse", artistName: "NF"}, ] nfsongs = {} dta.forEach(item => { if (item.artistName==="NF") { if (item.trackName in nfsongs) { nfsongs[item.trackName]++; } else { nfsongs[item.trackName]=1; } } }) for (key in nfsongs) { console.log(`${key} has ${nfsongs[key]} plays`) }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM