使用Kotlin按字母排序数组

时间:2018-11-17 12:57:11

标签: kotlin

我正在为手机创建启动器,我需要按字母对应用程序进行排序。

# view

 class PostListView(ListView): 
    ...
    def get_context_data(self, **kwargs):
        context = super(PostListView, self).get_context_data(**kwargs)
        context['category_wise_sorted_posts'] = Posts.objects.custom_category_dict()  # you can pass filter logic as well, like Posts.objects.custom_category_dict(author_id=1)
        return context


# template
{% for category, posts in category_wise_sorted_posts.items %}
<!-- Or {% for category, posts in user.posts_set.custom_category_dict.items %}  -->
     {{ category }}
     {% for p in posts %}
          {{ p.title }}

     {% endfor %}
{% endfor %}

这是我的列表类型(我真的不知道它是否称为列表类型,但希望您能理解):

 Appslist = ArrayList<AppInfo>()

    val i = Intent(Intent.ACTION_MAIN, null)
    i.addCategory(Intent.CATEGORY_LAUNCHER)
    val allApps = this.packageManager.queryIntentActivities(i, 0)

    for (ri in allApps) {
        val app = AppInfo()
        app.label = ri.loadLabel(this.packageManager)
        app.packageName = ri.activityInfo.packageName
        app.icon = ri.activityInfo.loadIcon(this.packageManager)
        if(app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toUpperCase() && searchWord != "" ||
            app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toLowerCase() && searchWord != "" ||
            app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.capitalize() && searchWord != "" ||
            app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord && searchWord != ""){

            if(app.packageName != "com.david.launcher" ){
                Appslist.add(app)
            }

        }
        if(searchWord == ""){
            if(app.packageName != "com.david.launcher"){
                Appslist.add(app)
            }
        }

    }

3 个答案:

答案 0 :(得分:4)

如果要归类到列表的副本,惯用的方法是对List使用sortedBy扩展方法。或在MutableList上使用sortBy扩展名,如果要就地排序而没有副本。 ArrayList可以用作任一列表类型。

// Sort a readonly list into a copy of the list

val appsList: List<AppInfo> = ...

val sortedAppsList = appsList.sortedBy { it.label?.toString() }

与之相对:

// Sort a mutable list in-place

val appsList: MutableList<AppInfo> = ...

appList.sortBy { it.label?.toString() }

,如果以ArrayList持有,则是相同的,但是直接引用此具体类型并不是惯用的。

// Sort an ArrayList list into a copy of the list

val appsList: ArrayList<AppInfo> = ...  // ALERT! not idiomatic

val sortedAppsList = appsList.sortedBy { it.label?.toString() }

// or if you want, feel free to sort in-place

appsList.sortBy { it.label?.toString() }

请注意toString()成员上的label: CharSequence。您必须小心对类型为CharSequence的引用进行排序,因为它是未定义的,它的排序行为是什么(请参阅:https://docs.oracle.com/javase/7/docs/api/java/lang/CharSequence.html

  

此接口不会优化equals和hashCode方法的常规协定。因此,比较两个实现CharSequence的对象的结果通常是不确定的。

如果CharSequence已经是String(很可能是),那么调用toString()就不会有任何危害,因为它只是返回自身。

还请记住,也必须处理可为空的CharSequence,并且您需要确定要为空值的位置:在列表的开头或结尾。我认为默认设置是让他们开始。


问题中有关代码的其他说明:

使用ListMutableList接口而不是具体的类来引用类型,并使用Kotlin stdlib中的方法对列表进行操作。对于不会更改的引用,也请使用val而不是var表示无论列表内容是否可能更改,它都将始终指向同一列表)。

从...开始,可以大幅度减少if的声明

if(app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toUpperCase() && searchWord != "" ||
    app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.toLowerCase() && searchWord != "" ||
    app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord.capitalize() && searchWord != "" ||
    app.label?.toString()!!.length >= searchWord.length && app.label?.toString()!!.substring(0, searchWord.length) == searchWord && searchWord != ""){

    if(app.packageName != "com.david.launcher" ){
        Appslist.add(app)
    }

}
if(searchWord == ""){
    if(app.packageName != "com.david.launcher"){
        Appslist.add(app)
    }
}

更简单:

if (app.packageName != "com.david.launcher" &&
        (searchWord.isBlank() || 
         app.label?.startsWith(searchWord, ignoreCase = true) == true)) {
    appsList.add(app)
}

您应该browse the standard library来了解可用的工具,以便为将来扩展工具包。

答案 1 :(得分:0)

您可以使用Collections.sort()和运行在AppInfo.label上的Comparator<AppInfo>的自定义实现来执行此操作,或者使AppInfo类实现Comparable接口并实现compareTo方法只是比较标签字段。

答案 2 :(得分:0)

class CustomClass {
    var id: String = ""
    var name: String = ""
}

fun sortAlphabetically(arrayList: ArrayList< CustomClass >): ArrayList< CustomClass >{
        var returnList: ArrayList< CustomClass > = arrayListOf()
        var list = arrayList as MutableList< CustomClass >
        list.sortWith(Comparator { o1: CustomClass, o2: CustomClass ->
            o1.name.compareTo(o2.name)
        })
        returnList = list as ArrayList< CustomClass >
        return returnList
    }