在 map 函数中组合数组

Combine arrays in map function

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

我通过地图收到一些 API 调用,我可以 console.log 所有结果,这很好,但问题是我想将所有结果组合到一个数组中。

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 的数组中。

你试过把它们推到一个数组中吗?

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))
})

据我了解,您的获取结果是 data,对于 alpha 的元素,您将获得与 data 一样多的 returns大批。您希望将来自数据的 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
  },
...
]

你在哪里使用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 数组。