【问题标题】:Sublisting list of integers into lists of same integers将整数列表子列表到相同整数的列表中
【发布时间】:2015-03-14 23:42:43
【问题描述】:

您好,我有一个简单的问题。我从 API 获取数据,他们设置数据的方式是对象有一个 id,然后我将它返回到一个列表中。

所以我会得到一个像这样的对象列表:

List = {Object1, Object2, Object3, ..., ObjectN};

这些对象将有一个像这样的父 id:

List = {9, 9, 9, 10, 10, 10, 10}

我想将对象子列表到包含相同父 ID 的列表中。什么是一个体面的算法来完成这个?所以是这样的:

Object1's parent id is 9
Object2's parent id is 9
Object3's parent id is 9
Object4's parent id is 10
Object5's parent id is 10
Object6's parent id is 10

List<Object> = {Object1, Object2, Object3} // List of all objects with parent id 9
List<Object> = {Object4, Object5, Object6} // List of all objects with parent id 10

我也考虑过使用HashMap,这是好的做法吗?出于缩放目的,我相信对象列表永远不会超过数百或数千,因此我认为速度在这里不一定是一个大问题。

背景:语言是Java,一个Object会有这样的参数:

Object: {
    parentId: 
    name:
    //etc.
}

编辑:我考虑得越多,我就越考虑使用排序算法

感谢 SamV:

public HashMap<Integer, List<Object>> createHashMap() {
    myHashMap = new HashMap<>();

    for (Object object : mObjectList) {
        int parentId = object.getParentId();
        if (!myHashMap.containsKey(parentId)) {
            List<Object> newList = new ArrayList<>();
            myHashMap.put(parentId, newList);
        }

        myHashMap.get(parentId).add(object);
    }

    return myHashMap;
}

【问题讨论】:

  • 因此,如果您有对象并且对象具有 parentId,似乎使用 HashMap 对对象进行排序是 HashMap 键是父 ID 的最佳解决方案。循环遍历列表,并以父 ID 作为键和新列表(如果该条目不存在)初始化一个新的 HashMap 条目,然后添加对象..
  • 您的用例尖叫着使用地图接口。您可能还想考虑其他实现,例如 TreeMap。
  • 这是什么语言的?并且这些列表是否没有一起返回,例如作为一个对象列表,其中对象具有 parentid 属性?

标签: algorithm list divide sublist


【解决方案1】:

在上述和我的正确理解之前,这是一个一直在解决的问题。伪代码会是这样的......

fn sortObjects(List objects) {
    var sortedParentHashMap = new HashMap();

    foreach(object in objects) {
        // If the HashMap entry for the current parentId does not exist then initialize
        if (!sortedParentHashMap.exists(object.parentId)) 
            // Initialize the entry with a new list
            sortedParentHashMap.put(object.parentId, new List());
        }
        // Now put the object within the specified parentId list
        sortedParentHashMap.get(object.parentId).put(object);
    }

    return sortedParentHashMap();
}

您使用每个对象的parentId 为您执行排序。您访问该parentId 的条目并将对象添加到列表中。如果您有重复项,您可以将 new List() 设为 HashMap 以检测重复项,就像您通过 parentId 进行排序一样。

HashMaps 通常是 O(1),所以性能应该很高。

【讨论】:

  • @AndyRoid 你用的是什么编程语言?如果我知道的话,我可以提供一个例子..
  • 我正在使用 Java,但语言无关紧要,我可以很好地阅读您的示例。如果你真的想用java写,那也很酷
  • 它有效!感谢您如此快速的回复和回复,我用 Java 实现更新了问题,并将继续接受您的回答。
  • @AndyRoid 太棒了,希望你明白它是如何工作的!
  • 我完全同意,如果 hashmap 不包含该 parentId,则使用该 parentId 创建一个新的对象列表,一旦 if 语句结束,将其添加到该列表中。如果它已经包含它,那么它只是循环内的一行代码。再次感谢 SamV!
【解决方案2】:

我还是决定写一个 Python 版本。

它使用集合模型中的 defautdict 类,因此您可以在 Java 示例的 for 循环中去掉 if 语句,因为第一次在 defaultdict 中使用键时,会返回一个新的空列表作为值。

与上面显示的 Java 等效的是:

from collections import defaultdict

id2obj = defaultdict(list)
for obj in objects:
    id2obj[obj.parentId].append(obj)

如果你想尝试一下,那么我写的小例子和类定义如下:

from pprint import pprint as pp
from collections import defaultdict

class AnObject():
    def __init__(self, parentId, name):
        self.parentId, self.name = parentId, name

    def __repr__(self):
        return "%s(%i)" % (self.name, self.parentId)

objects = [AnObject(id, "Obj%i" % n)
           for n, id in enumerate([9, 9, 9, 10, 10, 10, 10], 1)]
print('# OBJECTS')
pp(objects)

id2obj = defaultdict(list)
for obj in objects:
    id2obj[obj.parentId].append(obj)
print('\n# BY ID')
pp(dict(id2obj))

程序输出为:

# OBJECTS
[Obj1(9), Obj2(9), Obj3(9), Obj4(10), Obj5(10), Obj6(10), Obj7(10)]

# BY ID
{9: [Obj1(9), Obj2(9), Obj3(9)], 10: [Obj4(10), Obj5(10), Obj6(10), Obj7(10)]}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    • 2021-03-24
    • 2013-01-16
    • 1970-01-01
    相关资源
    最近更新 更多