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.map
и array.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;
};
}
(*: количество фактического веселья, содержащегося в ответе, может быть ограничено)