2009-11-28 90 views
1

我要通过一组记录下面的JavaScript循环,并提醒在阵列中找到匹配的数量,每个字段:获取JavaScript的一个数组中搜索一个数组

mymusic=[{title:"a",artist:"b",artwork:"c",tracks:[{tracktitle:"d",trackmp3:"e"}]}]; 
tracksArray=[]; 
trackTitles=[]; 
var albumScore=0; 
var artistScore=0; 
var tracksScore=0; 
stringToSearchFor="d"; 
for(i=0;i<mymusic.length;i++){ 
    if((mymusic[i].title).match(stringToSearchFor)) 
     albumScore+=1; 
    } 
if(albumScore!=0) 
    alert(albumScore+" match(es) found in Albums"); 
else 
    alert("No matches found in Albums"); 
for(d=0;d<mymusic.length;d++){ 
    if((mymusic[d].artist).match(stringToSearchFor)) 
     artistScore+=1; 
    } 
if(artistScore!=0) 
    alert(artistScore+" match(es) found in Artists"); 
else 
    alert("No matches found in Artists"); 
for(f=0;f<mymusic.length;f++){ 
    tracksArray[f]=mymusic[f].tracks; 
    for(g=0;g<tracksArray;g++){ 
     trackTitles[g]=tracksArray[g].tracktitle; 
     } 
    for(h=0;h<trackTitles.length;h++){ 
     if(trackTitles(h).match(stringToSearchFor)) 
      { 
      tracksScore+=1; 
      } 
     } 
    } 
if(tracksScore!=0) 
    alert(tracksScore+" match(es) found in Tracks"); 
else 
    alert("No matches found in Tracks"); 

工作正常对于“标题”和“艺术家”记录,但总是会提示“未找到匹配”的“曲目”记录,即使有匹配。我想问题是通过trackTitles数组的嵌套for循环,但我不明白我可以改变,使其工作。有任何想法吗? 感谢

+0

下次将它分解为方法。这段代码看起来不可读:( – 2009-11-29 22:22:07

回答

0

试试这个:

var tracksScore=0; 
stringToSearchFor="d"; 
for(var f=0;f<mymusic.length;f++){ 
    var tracksArray=mymusic[f].tracks; 
    for(var g=0;g<tracksArray.length;g++) { 
     var tracktitle=tracksArray[g].tracktitle; 
     if(tracktitle.match(stringToSearchFor)) 
     { 
       tracksScore+=1; 
     } 
    } 
} 
if(tracksScore!=0) 
    alert(tracksScore+" match(es) found in Tracks"); 
else 
    alert("No matches found in Tracks"); 
+0

应该是'var f'和'var g' – 2009-11-28 20:01:55

+0

修正了,谢谢。这是原始代码中的一个错误。我试图修复代码而没有做太多的修改,但我想我可以有修正了这个错误。 – 2009-11-28 20:09:02

0

你有一些最终从有太多的变数干基本的错误。这里是你的代码重构: -

mymusic=[{title:"a",artist:"b",artwork:"c",tracks:[{tracktitle:"d",trackmp3:"e"}]}]; 
var albumScore=0; 
var artistScore=0; 
var tracksScore=0; 
stringToSearchFor="d"; 

for (var i=0; i < mymusic.length; i++) 
{ 
    if(mymusic[i].title.match(stringToSearchFor)) 
     albumScore += 1; 

    if(mymusic[i].artist.match(stringToSearchFor)) 
     artistScore += 1; 

    for (var j = 0; j < mymusic[i].tracks.length; j++) 
    { 
     if (mymusic[i].tracks[j].tracktitle.match(stringToSearchFor)) 
      tracksScore += 1 
    } 
} 

if (albumScore != 0) 
    alert(albumScore + " match(es) found in Albums"); 
else 
    alert("No matches found in Albums"); 

if (artistScore != 0) 
    alert(artistScore + " match(es) found in Artists"); 
else 
    alert("No matches found in Artists"); 

if (tracksScore != 0) 
    alert(tracksScore+" match(es) found in Tracks"); 
else 
    alert("No matches found in Tracks"); 
2
if(trackTitles(h) 

你调用数组。应该是方括号。

你可以将数组处理的东西分解为可重用的函数,以提高可读性并减少这些零散变量的数量。

由于有与已的程序办法的答案,这里是一个基于功能状阵列处理额外的乐趣(*):

function countItemsContaining(seq, prop, str) { 
    return seq.map(itemGetter(prop)).filter(function(s) { 
     return s.indexOf(str)!==-1; 
    }).length; 
} 

function itemGetter(prop) { 
    return function(o) { 
     return o[prop]; 
    }; 
} 


mymusic= [{title:"a",artist:"b",artwork:"c",tracks:[{tracktitle:"d",trackmp3:"e"}]}]; 
needle= 'd'; 

var titleScore= countItemsContaining(mymusic, 'title', needle); 
var artistScore= countItemsContaining(mymusic, 'artist', needle); 

// Calling concat is a JavaScript idiom to combine a load of lists into one 
// 
var mytracks= [].concat.apply([], mymusic.map(itemGetter('tracks'))); 
var tracksScore= countItemsContaining(mytracks, 'tracktitle', needle); 

array.maparray.filter在ECMAScript中第五版是标准化的,但不在IE中尚未提供,所以兼容性,你可以将它们定义是这样的:

if (!('map' in Array.prototype)) { 
    Array.prototype.map= function(f, that) { 
     var a= new Array(this.length); 
     for (var i= 0; i<this.length; i++) if (i in this) 
      a[i]= f.call(that, this[i], i, this); 
     return a; 
    }; 
} 

if (!('filter' in Array.prototype)) { 
    Array.prototype.filter= function(f, that) { 
     var a= []; 
     for (var i= 0; i<this.length; i++) if (i in this) 
      if (f.call(that, this[i], i, this)) 
       a.push(this[i]); 
     return a; 
    }; 
} 

(*:包含在回答实际有趣量可能有限)

1

看看名为underscore.js的图书馆。它是为了这种东西而设计的。这些任务通常归结为一行或两行易于阅读的代码。

它在可用时使用本机方法,填充缺少的位(取决于浏览器)并且是可链接的。它甚至使得内置的数组方法是可链接的。

0

AnthonyWJones和bobince说了什么(尽管我需要花一些时间阅读bobince的回答)。

另一种解决方案:当我看到数据结构的时候,我认为是“递归!”并认为看看我是否能够提出一种可以处理任何(未知)深度级别的任意大小的数据结构的解决方案会很有趣。

我不会频繁编写代码,所以下面的代码可能充满了不好的做法,但它的工作原理:)。让我知道你的想法。

myMusic=[{title:"a",artist:"b",artwork:"c",year:"d",tracks:[{tracktitle:"d",trackmp3:"e"}]}]; 

function find_match(dataObj,stringToSearchFor,resultObj){ 

    resultObj = (resultObj)?resultObj:{}; //init resultObj 

    for (dataKey in dataObj){ //loop through dataObj 
    if (typeof(dataObj[dataKey]) == "object"){ //if property is array/object, call find_match on property 
    resultObj = find_match(dataObj[dataKey],stringToSearchFor,resultObj); 
    }else if (dataObj[dataKey].match(stringToSearchFor)){ //else see if search term matches  
     resultObj[dataKey] = (resultObj[dataKey])?resultObj[dataKey] +=1:1; //add result to resultObj, init key if not yet found, use dataObj key as resultObj key 
    } 
    } 

    return resultObj; //return resultObj up the chain 

} 

results = find_match(myMusic,"d"); 

alertString = ""; 

for (resultKey in results){ //loop through results and construct alert msg. 
    alertString += results[resultKey] + " match(es) found in " + resultKey + "\n"; 
} 

alert(alertString); 
相关问题