繁体   English   中英

优化代码:有没有更好的方法将 map 一个(较短的)数组转换为 Javascript 中的另一个(较长的)对象数组?

[英]Refining code: Is there a better way to map one (shorter) array to another (longer) array of objects in Javascript?

我有一个 React 项目,它使用一组 colors 来设置一些样式:

export const backlightArray = [
    theme.capri,
    theme.aqua,
    theme.oceanGreen,
    theme.yellow,
    'orange',
    theme.lightRed
];

和另一个具有锚标签属性的对象数组:

const siteStart = [
    { label: 'StackOverflow', href: 'https://stackoverflow.com' },
    { label: 'rwieruch', href: 'https://www.robinwieruch.de/blog' },
    { label: 'ITNext.io', href: 'https://itnext.io/' },
    { label: 'Dev.to', href: 'https://dev.to/' },
    {
        label: `ycombninator ('Hacker News')`,
        href: 'https://news.ycombinator.com/'
    },
    { label: 'OpenBase.io', href: 'https://openbase.io/' },
    { label: 'Coolors.co', href: 'https://coolors.co/' },
    { label: 'GitHub', href: 'https://www.github.com/' },
    { label: '/r/homelab/', href: 'https://www.reddit.com/r/homelab/' },
];

(我已经缩短了这个例子,但现在这个数组有 14 个链接)。

colors 数组比站点对象数组短。 我希望 colors 在 colors 阵列结束后重复,所以我想出了这个循环,从backlightArray阵列中添加 colors 以获得siteStart阵列的长度:

let siteListColorsArray = [];
for (let i = 0; i < siteStart.length; i++) {
    if (siteListColorsArray.length < siteStart.length) {
        backlightArray.map(color => siteListColorsArray.push(color));
    }
}

然后是 map 那些 colors 以及链接的其他共享属性,如下所示:

const sites = siteStart.map((site, idx) => {
    site.target = '_blank';
    site.rel = 'noopener noreferrer';
    site.id = `${site.label.slice(0, 3)}-${idx}`; // this is for 'key'
    site.color = siteListColorsArray[idx];
    return site;
});

export default sites;

我是这样写的,所以我可以在siteStart数组中添加 /remove labelhref对象,而不必弄乱已完成对象中的任何其他属性。

它工作正常,但我只是想知道:这段代码对其他人来说看起来不错吗? 如果你要做类似的事情,你会做哪些不同的事情?

我认为这应该为您完成工作:

colorsLastIndex = backlightArray.length - 1;

const sites = siteStart.map((site, idx) => {
  const newIndex = idx > colorsLastIndex ? (idx % colorsLastIndex) - 1 : idx;
  site.id = `${site.label.slice(0, 3)}-${idx}`; // this is for 'key'
  site.color = backlightArray[newIndex];
  return site;
});

我得到了一个很好的答案,它替换了这个嵌套循环来创建一个更长的 colors 数组:

let siteListColorsArray = [];
for (let i = 0; i < siteStart.length; i++) {
    if (siteListColorsArray.length < siteStart.length) {
 /* lengths: (0)                           (13)            */
        backlightArray.map(color => siteListColorsArray.push(color));
 /*      (length = 6)                (iterates until > 13)         */
    }
}

一旦索引大于 5 (backlightArray.length -1) ,使用此三元表达式从index % backlightArray.length的模数中减去 1:

let colorsLastIndex = backlightArray.length - 1;

const sites = siteStart.map((site, idx) => {
    site.id = `${site.label.slice(0, 3)}-${idx}`;
    const newIndex = idx > colorsLastIndex ? (idx % colorsLastIndex) - 1 : idx;
    site.color = backlightArray[newIndex];
    return site;
});

但是,此解决方案使newIndex返回 -1,导致该迭代缺少颜色值。 当我使用console.log(newIndex)时,你可以看到数字低于 0 并且没有返回到 5 - 我写了步骤来说明(我在控制台中执行了计算以验证):

/* start first iteration w/ index */
0
1
2
3
4
5
/* start newIndex = idx > colorsLastIndex ? (idx % colorsLastIndex) - 1
                    (6)       (6)            (6)      (5)          (- 1)  */
0  // 6 % 5 - 1  
1  // 7 % 5 - 1 
2  // 8 % 5 - 1 
3  // 9 % 5 - 1 
-1 // 10 % 5 - 1 
0  // 11 % 5 - 1 
1  // 12 % 5 - 1 
2  // 13 % 5 - 1 

这是对我有用的解决方案(注意: backlightArray.length = 6):

const newIndex = idx >= backlightArray.length ? idx % backlightArray.length : idx;
    site.color = backlightArray[newIndex];

console.log(newIndex): 
/* start first iteration w/ idx */
0
1
2
3
4
5
/* start newIndex = (idx) >= backlightArray.length ? idx % backlightArray.length 
                     (6)           (6)               (6)  %  (6) */
0  // 6 % 6
1  // 7 % 6
2  // 8 % 6
3  // 9 % 6
4  // 10 % 6
5  // 11 % 6
0  // 12 % 6
1  // 13 % 6

一旦索引达到 6,即 1 高于 5( backlightArray中的最后一种颜色),6 = backlightArray.length ,则条件变为 true。 然后,索引除以 6 的余数等于 0,然后增加 1,直到索引达到另一个 6 倍数(例如 12),此时它再次变为 0。 这种情况也适用:

newIndex = idx + 1 > backlightArray.length ? idx % backlightArray.length : idx;

idx + 1可能更能说明逻辑。

这是一个很好的模式,可以减少对笨拙的嵌套循环的需求。 非常感谢分享!

暂无
暂无

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

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