【问题标题】:Combine arrays in map function在 map 函数中合并数组
【发布时间】:2021-06-06 19:40:48
【问题描述】:

我有一个问题,或者至少我没有解决方案。

我通过地图获得了一些 API 调用,我可以控制台记录所有结果,这很棒,但问题是我想将所有结果合并到一个数组中。

var alpha = ['a', 'b', 'c', 'd', 'e'];

alpha.map(alpha => {
 fetch(`https://myurl.com/api/members/page?prefix=${alpha}`)
 .then(res => res.json())
 .then(data => matches.push)
 .then(() => console.log(matches))
})

我想我必须做一些等待什么的?

我的 API 响应如下所示:

{"list_complete":true,"keys":
    [
        {
            "username": "name.com",
            "uuid": "-47c9-88b6-2474090c7927",
            "user_type": 1,
            "subscribed": "false",
            "lastLogin": 1611066809086,
            "profile": {
                "name": "Name Lastname",
                "email": "name.com",
                "uuid": "3e92f458-6331-2-88b6-2474090c7927",
                "address": "",
                "history": [
                    {
                        "titleId": "5fac58f764e6710017411e79",
                        "posterUrl": "url.jpg",
                        "displayName": "Guns N ´ Roses - Appetite for Democracy",
                        "t": 0,
                        "d": 8492.2
                    },
                    {
                        "titleId": "5f7eadb3963c170017a919f3",
                        "posterUrl": "url.jpg",
                        "displayName": "Frank Zappa - Apostrophe Overnite Sensation (Classic Albums)",
                        "t": 7.728575,
                        "d": 2974.9
                    },
                    {
                        "titleId": "5e4463a395c832405e7effc0",
                        "posterUrl": "url.jpg",
                        "displayName": "Bob Marley - Uprising Live!",
                        "t": 3285.406821,
                        "d": 6807.7
                    },
                    {
                        "titleId": "5f80c6d0045fdf0017735019",
                        "posterUrl": "url.jpg",
                        "displayName": "Van Morrison - In Concert",
                        "t": 3610.529879,
                        "d": 4558.29
                    },
                    {
                        "titleId": "5fa85aba9c4a1900177e5cf9",
                        "posterUrl": "url.jpg",
                        "displayName": "Iron Maiden - En Vivo!",
                        "t": 2522.988949,
                        "d": 3380.5
                    },
                    {
                        "titleId": "5f719cb75d994e0017b429c5",
                        "posterUrl": "url.jpg",
                        "displayName": "Placebo - Placebo Live At The O2 Brixton Academy",
                        "t": 1426.589863,
                        "d": 5061.89
                    },
                    {
                        "titleId": "5fb3fd1731be640017c2f878",
                        "posterUrl": "https://slam-assets.s3.eu-north-1.amazonaws.com/staging/5fb3fd1731be640017c2f878/cover/1606214166013_nirvanastaende.jpg",
                        "displayName": "Nirvana - Nevermind (Classic Albums)",
                        "t": 0,
                        "d": 2948.69
                    }
                ],
                "favourites": [
                    "5f9039ed1279d600170378c2",
                    "5facf94364e6710017411e7d",
                    "5e4463a395c832405e7effc0"
                ]
            },
            "subscription": null
        }
    ]
}

而我要收集的数据在每个用户名下的一个叫history的数组中。

【问题讨论】:

  • 查看Promise.all及相关方法。您打算如何使用结果值?
  • 酷。谢谢。会看看。收集完所有数据后,我会将所有用户历史记录合二为一。
  • 如果matches 是一个数组,matches.push 不会做太多事情。如果您想将data 推入matches(或then(data => { matches.push(data); }),则需要.then(matches.push),这样您就不会得到matchespush 的输出)的新长度的响应。
  • 查看此处查看使用Promise.all()的示例:flaviocopes.com/how-to-wait-multiple-promises-javascript
  • @HereticMonkey 我知道,你不能再编辑评论了,但为了记录,.then(matches.push) 将无法工作,因为method context being lost;它必须是.then(matches.push.bind(matches))

标签: javascript node.js svelte sapper


【解决方案1】:

据我了解,您将获得data 作为您获取的结果,并且您将获得dataalpha 数组元素的尽可能多的返回。您想将来自数据的history 对象的结果组合成一个单一的一维数组。这意味着您的目标数组如下所示:

histories = [{},{},{} ... ]

其中每个对象{} 是一个历史元素。

为了执行所需的操作,我们需要首先访问keys 元素并遍历所有这些元素,从每个元素中检索history 内容。但是,您提到history 对于用户来说可能存在也可能不存在,因此我们需要检查它的存在。

所以,总结一下:

  • 我们需要遍历keys的所有元素

  • 我们需要检查上述元素中是否存在history,然后再尝试对其进行处理。

我们可以通过在data.keys 上使用forEach() 方法来执行第一个操作,同时使用简单的if (element.profile.history) 来检查history 的存在:

var alpha = ['a', 'b', 'c', 'd', 'e'];
const histories = [];

alpha.map(alpha => {
    fetch(`https://myurl.com/api/members/page?prefix=${alpha}`)
        .then(res => res.json())
        .then(data => data.keys.forEach(function (e) { //Iterate through the keys
            if (e.profile.history) { //If history is present
                histories.push(...e.profile.history); //Pushing to array with spread sytnax
            }
        })
        )
})

为了拥有一个包含所有 history 项目的单个数组,我们使用了扩展 ... 语法,您可以阅读更多关于它的信息 here

所以输出:

console.log(histories)

然后会屈服:

[
  {
    titleId: '5fac58f764e6710017411e79',
    posterUrl: 'url.jpg',
    displayName: 'Guns N ´ Roses - Appetite for Democracy',
    t: 0,
    d: 8492.2
  },
  {
    titleId: '5f7eadb3963c170017a919f3',
    posterUrl: 'url.jpg',
    displayName: 'Frank Zappa - Apostrophe Overnite Sensation (Classic Albums)',
    t: 7.728575,
    d: 2974.9
  },
  {
    titleId: '5e4463a395c832405e7effc0',
    posterUrl: 'url.jpg',
    displayName: 'Bob Marley - Uprising Live!',
    t: 3285.406821,
    d: 6807.7
  },
...
]

【讨论】:

  • 这么大的帮助。再次非常感谢。当然,我投了赞成票并将其标记为已解决。我学到了很多,测试了很多。所以我很感激。是的,我也是这么想的,但是当我试图将它循环出来时无法在外面访问它。
  • 完全没有问题,非常感谢!关于这个其他问题:histories 实际上可以从map() 函数外部访问,您可以通过在 map()` 之外执行类似console.log(histories[0].titleId) 的操作来尝试自己,因为这将打印 first 历史。这或多或少是您想要做的吗?
【解决方案2】:

你试过将它们推入一个数组吗?

var alpha = ['a', 'b', 'c', 'd', 'e'];
const results = [];

alpha.map(alpha => {
fetch(`https://myurl.com/api/members/page?prefix=${alpha}`)
  .then(res => res.json())
  .then(data => results.push(data))
})

【讨论】:

  • 是的,然后我得到一个数组,但在那个数组中我仍然有 5 个不同的数组。想把它编译成一个数组。
  • 尝试将:then(data => results.push(data)) 更改为:.then(data => results.push(...data))
【解决方案3】:

你在哪里使用alpha.map,我建议alpha.forEach,因为你只是在那里循环,而不是映射。

您可以使用await 代替.then,但这正是您处理从await 返回的Promise 的方式。


const urls = [/* your urls here */];
const matches = [];
urls.forEach( url => {
  const res = await fetch(url);
  const json = await res.json();
  matches.push(json);
});
console.log(matches);

使用您现有的样式,将data 推入matches 数组,完成后记录:

var alpha = ['a', 'b', 'c', 'd', 'e'];
var matches = [];
alpha.forEach(alpha => {
 fetch(`https://myurl.com/api/members/page?prefix=${alpha}`)
 .then(res => res.json())
 .then(data => matches.push(data))
});
console.log(matches);

您可以使用Promise.all 并行运行fetch 调用,但这是另一回事。

我认为您的 JSON 可能以数组形式返回,所以您最终得到了一个数组数组?查看Array.concat,并使用它将res.json 添加到matches 数组中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多