【问题标题】:Sort list of objects javascript排序对象列表javascript
【发布时间】:2019-07-18 10:09:54
【问题描述】:

我有以下列表,从 api 获取数据:

 const Studentdata = {
   "StudentName1": {
        "active": true,
        "gender": "male" 
    },
    "StudentName2": {
        "active": false,
        "gender": "male" 
    },
    "StudentName3": {
        "active": false,
        "gender": "female" 
    },
   "StudentName4": {
        "active": true,
        "gender": "female" 
    },
   "StudentName5": {
        "active": true,
        "gender": "female" 
    },
    "StudentName6": {
        "active": false,
        "gender": "female" 
    }
}

我这样渲染这些数据:

Object.keys(Studentdata).map(item => {
    return (
         <>
             <span>{item}</span>
             // will use {Studentdata[item]} list to render ul,li
    )

 })

所以,在这里我想根据她/他是否活跃来过滤学生数据,活跃的真实项目应该首先出现。预期的操作是:

const Studentdata = {
   "StudentName1": {
        "active": true,
        "gender": "male" 
    },
    "StudentName4": {
        "active": true,
        "gender": "male" 
    },
    "StudentName5": {
        "active": true,
        "gender": "female" 
    },
   "StudentName2": {
        "active": false,
        "gender": "female" 
    },
   "StudentName3": {
        "active": false,
        "gender": "female" 
    },
    "StudentName6": {
        "active": false,
        "gender": "female" 
    }
}

我在 React js 中使用它,所以我需要精确的格式来渲染/重新渲染 DOM。因为,我需要这个“StudentName1”来显示学生姓名,我将显示他的详细信息。我能够得到以下内容:

Object.values(Studentdata).sort((a, b) => b.active - a.active)

但这给了我:

[0: {active: true, gender: "male"},
1: {active: true, gender: "female"},
2: {active: true, gender: "female"},
3: {active: false, gender: "male"},
4: {active: false, gender: "female"}]

但是如果我渲染这个我需要改变渲染方法,所以需要我上面提到的格式。谢谢

【问题讨论】:

    标签: javascript reactjs function object ecmascript-6


    【解决方案1】:

    问题是您只使用values() 来执行排序,而您也应该使用键对对象进行排序。您遇到的另一个问题是,希望您的对象键按特定顺序排列通常不是一个好习惯。将渲染函数更改为results.map 而不是Object.keys(results).map 更有意义。这是您想要的输出:

    const Studentdata = {
     "StudentName1": {
          "active": true,
          "gender": "male" 
      },
      "StudentName2": {
          "active": false,
          "gender": "male" 
      },
      "StudentName3": {
          "active": false,
          "gender": "female" 
      },
     "StudentName4": {
          "active": true,
          "gender": "female" 
      },
     "StudentName5": {
          "active": true,
          "gender": "female" 
      },
      "StudentName6": {
          "active": false,
          "gender": "female" 
      }
    }
    
    const sorted = Object.entries(Studentdata)
      .sort((a, b) => b[1].active - a[1].active)
      .reduce((r, [key, value]) => {
        r[key] = value
        return r
      }, {})
      
    console.log(sorted)

    如果您删除reduce(),您将获得您想要的结果,但只是在一个数组中。这是更可取的,因为 reduce 是多余的,因为无论如何您都使用Object.keys() 将其转回数组。此外,虽然这些天应该保持关键顺序,但依赖它仍然感觉不直观。

    【讨论】:

    • 如果我删除 reduce() 我没有得到想要的输出。
    • 我说,'但只是在一个数组中',如果你删除 reduce(数据仍然相同)。您需要改进渲染函数以使用数组而不是对象。
    【解决方案2】:

    在准备渲染时对对象的条目(不仅仅是键)进行排序,以便您拥有一个同时包含键和关联值的排序数组:

    Object.entries(Studentdata)
      .sort((a, b) => b[1].active - a[1].active)
      .map(([name, { active, gender }]) => (
        // render ul, li with variables name, active, and gender
      ))
    

    【讨论】:

    • 我可以知道[name, { active, gender }] 中方括号调用的术语是什么吗?
    • 那是解构。如果item 是一个数组,您可以使用[val0, val1] 来代替item 来提取数组的第0 个和第一个索引。同样,如果val1 是一个对象,您可以使用{ active, gender } 来提取val1activegender 属性。
    【解决方案3】:

    Object.entries 排序,然后在map 语句中重构对象(不幸的是使用eval 来保留变量名):

    const Studentdata = {
       "StudentName1": {
            "active": true,
            "gender": "male" 
        },
        "StudentName2": {
            "active": false,
            "gender": "male" 
        },
        "StudentName3": {
            "active": false,
            "gender": "female" 
        },
       "StudentName4": {
            "active": true,
            "gender": "female" 
        },
       "StudentName5": {
            "active": true,
            "gender": "female" 
        },
        "StudentName6": {
            "active": false,
            "gender": "female" 
        }
    };
    
    Object.entries(Studentdata).sort((a, b) => b[1].active - a[1].active).map(([ name: objName, { active, gender } ]) => (
        eval(`let ${objName} = { active: ${active}, gender: ${gender} }`);
        return (
            <>
                <span>{name}</span>
        )
    ));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多