【问题标题】:How to use filter method to return another property inside the object that passed the filter test?如何使用过滤器方法返回通过过滤器测试的对象内部的另一个属性?
【发布时间】:2019-12-13 11:44:09
【问题描述】:

我正在尝试使用 filtermap 方法迭代对象数组,以便返回包含属性名称 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


【解决方案1】:

您的 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);

【讨论】:

  • 啊,有道理。有没有一种方法或方法可以按我的意愿返回对象,而不是调用函数getSoundB 的返回/结果?或者,也许你已经在你的例子中做到了。我将不得不更仔细地查看您的代码示例。
  • 只需在getSoundB 中返回您需要的内容,当您记录它时该值就会出现:)
  • 我认为问题在于我想将函数调用(例如getSoundB('audio/34.wav', 1, false))添加到数组而不是它的返回值。这样我就可以调用该函数并在以后得到不同的结果。但也许我做错了事?我的程序已经通过引用数组中的调用来工作。我试图保留该逻辑,但从数组中过滤掉一些在给定时间不需要的调用/属性。
  • 您能否更新您的帖子,以便更全面地了解getSoundB 中发生的事情
  • 我刚刚在上面的问题中添加了 getSound 函数和相关代码,并描述了它是如何实现的。谢谢。
猜你喜欢
  • 2021-10-30
  • 1970-01-01
  • 2015-09-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-06
相关资源
最近更新 更多