javascript - 如何使用filter方法返回通过过滤测试的对象内部的另一个属性?

标签 javascript arrays object filter array.prototype.map

我正在尝试使用 filtermap 方法遍历对象数组,以便返回包含属性名称 的所有对象的数组note 其中 note== 到 'B' (var note = 'B')。问题是 filter 只从对象返回 'note: 'B'' 而我需要它返回对象中的其他属性:functionCall。过滤器仅返回 'note: 'B'' 但我需要的是 functionCall: getSoundB('audio/34.wav', 1, false)注意:'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 只返回了 'note: 'B'' 而没有包含 functionCall 属性。因此,当 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) ),并且我想确保该函数未被调用/执行(我希望我在这里正确使用调用和调用?)。在我实际程序的测试中,似乎没有在过滤过程中调用这些函数调用(这正是我想要的)。

最佳答案

您的 filterForMatchingNotes() 没有返回您期望的返回值,您返回的是返回 undefined 的函数的值,而不是整个对象。

const 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 getSoundB(a, b, c) {
  // does stuff
};

function filterForMatchingNotes(arrayName, note) {
  return arrayName
    .filter(obj => obj.note === note);
}

let note = 'B';
let tempFilterArray = filterForMatchingNotes(potentialThunderSounds, note);

console.log(tempFilterArray);

关于javascript - 如何使用filter方法返回通过过滤测试的对象内部的另一个属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57367263/

相关文章:

javascript - AST 到 JS 的代码转换器

javascript - 数组原型(prototype) TypeScript

javascript - 如何将图像源插入隐藏的输入值

c++ - 在 C++/G++ 中是否有*任何*方法来获取 C 样式数组的长度?

javascript - 具有新 ParentId 和 ChildId 的循环树

ruby - 如何使用函数在 ruby​​ 中操作对象数据的实例?

javascript - NPM 无法识别我的模块(需要未知模块)

javascript - 从 JavaScript 数组中删除对象?

javascript - 对象数组 : Create new object for each specified key that has a value

javascript - PHP javascript 关联数组