简体   繁体   English

在 Array.map() 的每次迭代之间保留变量的更好/内联方法?

[英]Better / Inline way to persist a variable between each iteration of Array.map()?

I have an array in which some elements are implicitly paired with other elements, but not necessarily adjacent.我有一个数组,其中一些元素与其他元素隐式配对,但不一定相邻。 I use Array.map over this array to create JSX elements (not important) but I need to keep track between each iteration of if I've already seen an elements pair.我在这个数组上使用Array.map来创建 JSX 元素(不重要)但是我需要在每次迭代之间跟踪我是否已经看到一个元素对。

The code is effectively as such:代码实际上是这样的:

let pairedElementsSeen= {};
return <...>
    {myArray.map(elem => {
        if (elem.pairKey in pairedElementsSeen) {
            return secondaryOption;
        }
        else {
            pairedElementsSeen[elem.key] = someValue;
            return defaultOption;
        }
    )}
</...>;

This already works as is, but I don't like that I need the extra pairedElementsSeen object which, because of the structure and length of the JSX, must be defined well in advance of where it is used.这已经按原样工作,但我不喜欢我需要额外的pairedElementsSeen object ,由于 JSX 的结构和长度,必须在使用它之前很好地定义它。 Is there some way with Array.map or else a similar function to be able to carry a variable like pairedElementsSeen between each iteration? Array.map或类似的 function 是否有某种方法能够在每次迭代之间携带像pairedElementsSeen这样的变量?

The only things I can think of would either be to我唯一能想到的就是

  1. Extract this whole section into a dedicated for loop before all of the JSX, which I don't like because it displaces the behavior from the place where it is used, or将整个部分提取到所有 JSX 之前的专用 for 循环中,我不喜欢它,因为它取代了使用它的地方的行为,或者
  2. Create a one-off, instantly called arrow function with the persistent object defined within.创建一个一次性的,立即称为箭头 function,其中定义了持久性 object。 I find these to be particularly un-intuitive when reading however and plus it will lose it's abilitiy to be combined inline with other array operations like sort or filter .然而,我发现这些在阅读时特别不直观,而且它会失去与sortfilter等其他数组操作内联组合的能力。

That would look like this ugly mess:这看起来像这样丑陋的一团糟:

return <...>
    {(() => {
        let pairedElementsSeen = {};
        return myArray.map(...);
    })()}
</...>;

Any other ideas?还有其他想法吗?

You could do it without the intermediate object (but less efficiently) like this:您可以在没有中间 object 的情况下这样做(但效率较低),如下所示:

return <...>
    {myArray.map((elem, i, arr) => {
        const pairedElementSeen = arr.findIndex(e => e.key === elem.pairKey) < i;
        return pairedElementSeen ? secondaryOption : defaultOption;
    })}
</...>;

O(n) way to do it (uses intermediate object but all in one array function call): O(n) 方法(使用中间 object 但全部在一个数组 function 调用中):

return <...>
    {myArray.reduce((agg, elem) => {
      if (elem.pairKey in agg.pairedElementsSeen) {
        agg.results.push(secondaryOption);
      } else {
        agg.pairedElementsSeen[elem.key] = true;
        agg.results.push(defaultOption);
      }

      return agg;
    }, { pairedElementsSeen: {}, results: [] }).results}
</...>;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM