如何在 Javascript 中的拼接数组中使用 .findIndex() 方法?

How can I use the .findIndex() method be used in spliced arrays in Javascript?

我一直在学习 Codecademy 上 JavaScript 课程的介绍 https://www.codecademy.com/courses/introduction-to-javascript/lessons/javascript-iterators/exercises/find-index 并认为我会尝试扩展他们的想法之一以搜索数组中以字符串 's'.

开头的所有字符串

我定义了一个名为 animals 的示例数组,并用一些字符串填充它。首先,我使用 .findIndex() 方法找到第一个以 's' 开头的动物名称,并将其值保存到名为 sIndex 的变量中。然后我尝试拼接来自 sIndex + 1 的动物数组,应用 findIndex(),然后用返回的值更新 sIndex

这是我目前的代码:

const animals = ['hippo', 'tiger', 'lion', 'seal', 'cheetah', 'monkey', 'salamander', 'elephant'];

//Create a function that finds all animals in the array animals starting with the letter s.

let sNameAnimals = [];
let sIndex = animals.findIndex(animal => animal[0] === 's');
let numOfAnimals = animals.length

while (sIndex !== -1){
    // Push the current found animal onto the array sNameAnimals
    sNameAnimals.push(animals[sIndex])
    // Find the next animal that starts with s in the animals array.
    animalSlice = animals.slice(sIndex+1);
    sIndex = animalSlice.findIndex(animal => animal[0] === 's');

}

但是,当我通过 node.js 在控制台中 运行 时,我收到以下错误消息:

<--- Last few GCs --->

[16999:0x103240000]   104105 ms: Mark-sweep 577.2 (588.5) -> 577.2 (581.5) MB, 1429.9 / 0.0 ms  (average mu = 0.913, current mu = 0.000) last resort GC in old space requested
[16999:0x103240000]   105504 ms: Mark-sweep 577.2 (581.5) -> 577.2 (581.5) MB, 1398.8 / 0.0 ms  (average mu = 0.801, current mu = 0.000) last resort GC in old space requested


<--- JS stacktrace --->

==== JS stack trace =========================================

    0: ExitFrame [pc: 0x2e143204fb7d]
Security context: 0x0d42a071d969 <JSObject>
    1: /* anonymous */ [0xd427bf849e9] [/Users/cmg18/Documents/Javascript/Iterators/iterators.js:~1] [pc=0x2e14320f0b82](this=0x0d427bf84b19 <Object map = 0xd42f1a82521>,0x0d427bf84b19 <Object map = 0xd42f1a82521>,0x0d427bf84ad9 <JSFunction require (sfi = 0xd42db01b049)>,0x0d427bf84a51 <Module map = 0xd42f1acbc21>,0x0d42db021c49 <String[56]: /Users/cmg18/Doc...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
 1: 0x10003a9d9 node::Abort() [/Users/cmg18/.nvm/versions/node/v11.0.0/bin/node]
 2: 0x10003abe4 node::FatalTryCatch::~FatalTryCatch() [/Users/cmg18/.nvm/versions/node/v11.0.0/bin/node]
 3: 0x10019ed17 v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [/Users/cmg18/.nvm/versions/node/v11.0.0/bin/node]
 4: 0x10019ecb4 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [/Users/cmg18/.nvm/versions/node/v11.0.0/bin/node]
 5: 0x1005a5882 v8::internal::Heap::FatalProcessOutOfMemory(char const*) [/Users/cmg18/.nvm/versions/node/v11.0.0/bin/node]
 6: 0x1005aedd4 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [/Users/cmg18/.nvm/versions/node/v11.0.0/bin/node]
 7: 0x10057d3c6 v8::internal::Factory::NewFixedArrayWithFiller(v8::internal::Heap::RootListIndex, int, v8::internal::Object*, v8::internal::PretenureFlag) [/Users/cmg18/.nvm/versions/node/v11.0.0/bin/node]
 8: 0x1005238c4 v8::internal::(anonymous namespace)::ElementsAccessorBase<v8::internal::(anonymous namespace)::FastPackedObjectElementsAccessor, v8::internal::(anonymous namespace)::ElementsKindTraits<(v8::internal::ElementsKind)2> >::GrowCapacity(v8::internal::Handle<v8::internal::JSObject>, unsigned int) [/Users/cmg18/.nvm/versions/node/v11.0.0/bin/node]
 9: 0x1007fec82 v8::internal::Runtime_GrowArrayElements(int, v8::internal::Object**, v8::internal::Isolate*) [/Users/cmg18/.nvm/versions/node/v11.0.0/bin/node]
10: 0x2e143204fb7d 

我不确定我在做什么导致了错误?我原以为我的 while 循环应该由于拼接而终止。

您需要Array#splice (delete or insert into an array) the array instead of using Array#slice(获取子数组)。

对于这种方法,您改变 animals 并获得另一个以 s 开头的所需项目数组。

const
    animals = ['hippo', 'tiger', 'lion', 'seal', 'cheetah', 'monkey', 'salamander', 'elephant'],
    sNameAnimals = []
    startsWithS = animal => animal[0] === 's';

let sIndex = animals.findIndex(startsWithS);

while (sIndex !== -1) {
    sNameAnimals.push(...animals.splice(sIndex, 1));
    sIndex = animals.findIndex(startsWithS);
}

console.log(sNameAnimals);

所以,基本上你已经使用了slice(即使你在问题标题中说了splice)。 我会建议你使用下面的代码,它基本上做同样的事情,步骤更少:

const animals = ['hippo', 'tiger', 'lion', 'seal', 'cheetah', 'monkey', 'salamander', 'elephant'];
const sNameAnimals = animals.filter(animal => animal[0] === "s");

我已经设法修复了我自己的代码,但可能还是有点啰嗦。我复制了动物数组,然后将其重新分配给循环中 animals.slice(sIndex + 1) 的输出。

const animals = ['hippo', 'tiger', 'lion', 'seal', 'cheetah', 'monkey', 'salamander', 'elephant'];

let sNameAnimals = [];
let sIndex = animals.findIndex(animal => animal[0] === 's');
let numOfAnimals = animals.length;
// Create a copy of animals
let animalsCopy = animals;

while (sIndex !== -1){
    // Push the current found animal onto the array sNameAnimals
    sNameAnimals.push(animalsCopy[sIndex])
    // Find the next animal that starts with s in the animals array.
    animalsCopy = animalsCopy.slice(sIndex+1);
    //console.log(animalsCopy);

    sIndex = animalsCopy.findIndex(animal => animal[0] === 's');
    //console.log(sIndex);

}