我正在尝试处理一个嵌套了2级深度的对象。例如,我的对象可以分解为以下形式:
TopLevel: [
MidLevel: [
LowLevel,
LowLevel,
.
.
],
MidLevel: [
LowLevel,
LowLevel,
.
.
]
.
.
]
基本上TopLevel
包含一个MidLevel
对象的列表,而每个对象又包含一个LowLevel
对象的列表。在处理结束时,我想为每个SomeObj
对象构建LowLevel
。但是SomeObj
需要来自TopLevel
,MidLevel
和LowLevel
的信息。
在过去的几个月中,我一直在尝试以更具功能性的风格编写代码,因此我的第一个想法是创建一个可以在对象的每个级别上构建的更高阶函数。该函数如下所示:
Function<MidLevel, Function<LowLevel, SomeObj>> buildObjects(TopLevel topLevel) {
return midLevel ->
lowLevel -> {
return buildSomeObj(topLevel, midLevel, lowLevel);
};
}
我打算以类似以下方式的方式使用此功能(假设我具有提供列表流的实用程序功能):
Function<MidLevel, Function<LowLevel, SomeObj>> topBuilder = buildObjects(topLevel);
List<SomeObj> objs = topLevel.streamMid()
.map(topBuilder)
.streamLow()
.map(Function::apply)
.collect(/*collect to list*/);
但是,这显然不起作用,因为一旦将MidLevel
对象应用于topBuilder
函数,我的流现在是函数流而不是MidLevel
对象,因此我不再不再可以访问流中的LowLevel
对象列表。
对此有任何解决方案吗?还是我不太想在功能上解决它?有没有办法既可以应用功能,又可以访问应用于该功能的原始对象?
答案 0 :(得分:6)
#settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'api',
]
#serializers.py
from rest_framework import serializers #<---- this line is giving me error
from .models import Plans
class PlansSerializer(serializers.ModelSerializer):
"""Serializer to map the Model instance into JSON format."""
class Meta:
"""Meta class to map serializer's fields with the model fields."""
model = Plans
fields = ('id', 'name', 'date_created', 'date_modified')
read_only_fields = ('date_created', 'date_modified')
和嵌套是必经之路。试试这个:
certifi==2018.11.29
Django==2.1.7
django-crispy-forms==1.7.2
django-filter==2.1.0
django-markdown==0.8.4
django-markdown2==0.3.1
django-pagedown==1.0.6
djangorestframework==3.9.2
djangorestframework-simplejwt==4.1.0
Markdown==3.0.1
markdown2==2.3.7
olefile==0.46
Pillow==5.4.1
Pygments==2.3.1
PyJWT==1.7.1
pytz==2018.9
通过这样的嵌套,您仍然可以访问外部函数中的元素,并且flatMap()
和topLevelStream() //create a stream of top level elements
.flatMap( top -> top.streamMid() //create a stream of mid level elements
.flatMap( mid -> mid.streamLow() //create a stream of low level elements
.map(low -> "use top, mid and low here")
)
)
.collect( ... );
的组合将flatMap()
所调用的流暴露给{{1} }。
答案 1 :(得分:1)
您可以简单地将flatMap
用作:
List<SomeObj> objs = topLevel.getMidLevels().stream()
.flatMap(a -> a.getLowLevels().stream().map(b -> topBuilder.apply(a).apply(b)))
.collect(Collectors.toList());
您的实体类似于:
class TopLevel {
List<MidLevel> midLevels;
}
class MidLevel {
List<LowLevel> lowLevels;
}
class LowLevel {
}
class SomeObj {
}