首页 > 解决方案 > 如何在此循环中动态选择要定位的提取?

问题描述

下面的函数将获取项目列表,然后我想将没有重复的数据存储在自己的数组中

async function fetchAtt() {
    let seturl = `https://wax.api.atomicassets.io/atomicassets/v1/templates?collection_name=mlb.topps&schema_name=promo&has_assets=true&page=1&limit=3414&order=desc&sort=created
    `;
    
    try {
        let res = await fetch(seturl);
        console.log(res);
        return await res.json();
    } catch (error) {
        console.log(error);
    }
}

在此处输入图像描述

然后它将返回一个唯一项目列表,然后我想创建一个循环遍历数据的函数,并存储来自“immutable_data”的数据,例如 img、name、legal、artist、rarity、variant。

在此处输入图像描述


我已经设法创建了这个函数,它将所有唯一名称存储在一个数组中,然后控制台记录它,但我需要创建一个函数,允许我传入参数,然后使用该参数作为 immutable_data 内部的目标

async function renderTags() {
    let atts = await fetchAtt();
    var flags = [], output = [], l = atts.data.length, i;
    for( i=0; i<l; i++) {
        if( flags[atts.data[i].immutable_data.variant]) continue;
        flags[atts.data[i].immutable_data.variant] = true;
        output.push(atts.data[i].immutable_data.variant);
    }
    console.log(output);
}

renderTags();

在此处输入图像描述

如您在上面看到的,如果我手动更改atts.data[i].immutable_data.variantatts.data[i].immutable_data.rarity

构建一个函数的最佳方法是什么,我可以传入一个 arg 并在immutable_data.

例如atts.data[i].immutable_data.name

标签: javascriptarraysjsonfetchfetch-api

解决方案


所有你需要的是

  • Array.prototype.map提取值。
  • Array.prototype.reduce用 aSet只获得不同的值。(然后用于Set.prototype.values()获取不同的值,但请注意values()不返回 "real" Array
    • 虽然使用Array.prototype.filter内部调用Array.prototype.indexOf也可以工作,但它的运行时性能会很糟糕(O(n*m)),而reduce使用 a Setis则要O(n)好得多。

第 1 部分:提取值:

async function renderTags() {

    const atts = await fetchAtt();

    if( !Array.isArray( atts.data ) )
    {
        throw new Error( "atts.data is not an array." );
    }
    
    const artists  = atts.data.map( d => d.immutable_data.artist );
    const rarities = atts.data.map( d => d.immutable_data.rarity );
    const variants = atts.data.map( d => d.immutable_data.variant );
    
    console.log( artists );
    console.log( rarities ); // [ "Legendary", "Epic", "Epic", "Super Rare", "Common" ]
    console.log( variants ); // [ "Gold", "Silver", "Silver", "Bronze", "Wood" ]
}

第 2 部分:提取不同的值:

async function renderTags() {

    const atts = await fetchAtt();

    if( !Array.isArray( atts.data ) )
    {
        throw new Error( "atts.data is not an array." );
    }
    
    const artists  = atts.data.map( d => d.immutable_data.artist ).reduce( ( set, e ) => set.set( e ), new Set() ).values();
    const rarities = atts.data.map( d => d.immutable_data.rarity ).reduce( ( set, e ) => set.set( e ), new Set() ).values();
    const variants = atts.data.map( d => d.immutable_data.variant ).reduce( ( set, e ) => set.set( e ), new Set() ).values();
    
    console.log( artists );
    console.log( rarities ); // [ "Legendary", "Epic", "Super Rare", "Common" ]
    console.log( variants ); // [ "Gold", "Silver", "Bronze", "Wood" ]
}

第 3 部分:使其成为一个可重用的函数:

  • immutable_data通过在初始第一遍中提取对象来简化内联函数。
  • 添加Array.from()以返回“真实” Arraysort这是很好的衡量标准。
function map_distinct( array, getter ) {

    const values   = array.map( getter );
    const distinct = values.reduce( ( set, e ) => set.set( e ), new Set() ).values();
    const asArray  = Array.from( distinct );
    asArray.sort(); 

    return asArray;
}

async function renderTags() {

    const atts = await fetchAtt();

    if( !Array.isArray( atts.data ) )
    {
        throw new Error( "atts.data is not an array." );
    }

    const imms = atts.data.map( d => d.immutable_data );
    
    const artists  = map_distinct( imms, d => d.artist );
    const rarities = map_distinct( imms, d => d.rarity );
    const variants = map_distinct( imms, d => d.variant );
    
    console.log( artists );
    console.log( rarities ); // [ "Common", "Epic", "Legendary", "Super Rare" ]
    console.log( variants ); // [ "Bronze", "Gold", "Silver", "Wood" ]
}

推荐阅读