【发布时间】:2019-12-13 11:44:09
【问题描述】:
我正在尝试使用 filter 和 map 方法迭代对象数组,以便返回包含属性名称 note 的所有对象的数组,其中 note 是 == 到 ' B' (var note = 'B')。问题是filter 只从对象返回'note: 'B'',我需要它返回对象中的另一个属性:functionCall。过滤器仅返回“note: 'B'”,但我需要的是functionCall: getSoundB('audio/34.wav', 1, false) 或note: 'B', functionCall: getSoundB('audio/34.wav', 1, false)。
这是我的示例程序:
function getSoundB(a, b, c) {
// does stuff
};
var potentialThunderSounds = [{
note: 'B',
functionCall: getSoundB('audio/34.wav', 1, false)
},
{
note: 'B',
functionCall: getSoundB('audio/35.wav', 1, false)
},
{
note: 'A',
functionCall: getSoundB('audio/36.wav', 1, false)
}
];
function filterForMatchingNotes(arrayName) {
return arrayName
.filter(function(obj) {
return obj.note == note;
})
.map(function(obj) {
return obj.functionCall;
});
}
var note = 'B';
var tempFilterArray = filterForMatchingNotes(potentialThunderSounds);
console.log('tempFilterArray.length: ' + tempFilterArray.length);
console.log('tempFilterArray: ' + tempFilterArray);
console.log('tempFilterArray string: ' + JSON.stringify(tempFilterArray));
当我运行我的程序时,数组中填充了两个空属性。原因似乎是因为filter 只返回了不包括属性functionCall 的'note: 'B''。因此,当map 去查找属性名称“functionCall”时,它并不存在。
我尝试按如下方式重组数组中的对象,以便 functionCall 位于属性 note 内,但这不起作用,因为看起来属性值不能是对象:
var potentialThunderSounds = [{
note: {'B', functionCall: getSoundB('audio/34.wav', 1, false)}
}];
这里是显示如何使用函数 getSound 的附加代码。我正在使用 Howler.js (Howler Docs):
/*
when getSound is called, it plays an audio file based on the params passed in.
*/
function getSoundB(soundFileName, sampleVolume, loop) {
var volumeMax = getRandom(optionNames[objectName].volumeMin, optionNames[objectName].volumeMax);
var volume = Math.floor(volumeMax * optionNames[objectName].objectVolume * sampleVolume / 100);
return new Howl({
src: [soundFileName],
autoplay: false,
loop: loop,
volume: volume,
fade: 0
});
}
/*
thunderPlayer accepts an integer as a parameter. It will then decide which specific sounds (listed as function calls inside the array potentialThunderSounds) will be played. It will push those sounds (aka function calls with a sound file as a parameter) into a temporary array so it can be called at a specific time later.
*/
function thunderPlayer(numberOfSoundsToPlay) {
var soundSequence = [];
for (var x = 0; x < numberOfSoundsToPlay; x++) {
var soundIndex = Math.round(Math.random() * (optionNames[objectName].potentialThunderSounds.length - 1));
soundSequence.push(optionNames[objectName].potentialThunderSounds[soundIndex]); // this pushes the the getSound function calls (which are elements in the array potentialThunderSounds) into an array so that they can be called at specific times later
}
playSoundIfThereIsOne();
function playSoundIfThereIsOne() {
var currentSound = soundSequence[0];
if (currentSound != undefined) { // stops call when there is no sound
currentSound.stereo(stereoPosition(objectName));
currentSound.play();
soundSequence.shift();
currentSound.once('end', playSoundIfThereIsOne);
}
}
}
编辑:关于解决方案的注释。
通过@MiroslavGlamuzina 的解决方案后,它似乎解决了我的问题。当使用他的代码过滤对象数组中的特定元素时,它似乎确实像我希望的那样返回了整个对象(而不仅仅是我正在过滤的对象中的特定名称/值对)。
我发现以下示例代码也说明了这一点:
var heroes = [{
name: 'Batman',
franchise: 'DC'
},
{
name: 'Ironman',
franchise: 'Marvel'
},
{
name: 'Thor',
franchise: 'Marvel'
},
{
name: 'Superman',
franchise: 'DC'
}
];
var marvelHeroes = heroes.filter(function(hero) {
return hero.franchise == 'Marvel';
});
console.log(marvelHeroes);
在示例中,元素“franchise”被过滤为包含字符串“Marvel”的元素,但返回整个对象:`{name: 'Thor', Franchise: 'Marvel'}'。
我有一个额外的考虑,我的数组中每个对象的元素值之一是函数调用(例如,getSoundB('audio/34.wav', 1, false)),我想确保该函数没有被调用/执行(我希望我在这里正确使用调用和调用?)。在我对实际程序的测试中,在过滤过程中似乎没有调用这些函数调用(这是我想要的)。
【问题讨论】:
-
问题在于
functionCall属性设置为调用getSoundB的结果,它返回undefined,这意味着filterForMatchingNotes将始终返回一个空数组或带有所有@ 的数组987654349@ 值。
标签: javascript arrays object filter array.prototype.map