使用 ramda 重新排列 JSON .js - 基于兄弟元素的镜头?



这是我的数据结构(缩写,你可以跳过这个,直到你到达下面我问题的核心):

var data = {
jsonapi: { version: '1.0' },
data: {
type: 'mobile_screens',
id: '1',
attributes: { title: 'Watch' },
relationships: {
mobile_screen_components: {
data: [
{ type: 'mobile_screen_components', id: '1_1' },
{ type: 'mobile_screen_components', id: '1_2' },
],
},
},
},
included: [
{
type: 'videos',
id: '5590720024001',
attributes: {
thumbnail: {
width: 1280,
url:
'http://media2.XXXXX.com/BrightCove/694940094001/2017/09/27/694940094001_5590729403001_5590720024001-vs.jpg?pubId=694940094001',
height: 720,
},
start_air_date: '2017-09-27T16:32:00.000Z',
streams: [
{
url:
'http://XXXXX-f.akamaihd.net/i/BrightCove/694940094001/2017/09/27/694940094001_55907,27023001_5590720024001,30873001_5590720024001,32416001_5590720024001,32423001_5590720024001,32792001_5590720024001,32896001_5590720024001,.mp4.csmil/master.m3u8',
mime_type: 'MP4',
},
],
last_modified_date: '2017-09-27T16:50:13.471Z',
description: 'House Republicans renew call amid fresh Comey concerns',
},
},
{
type: 'videos',
id: '5590670324001',
attributes: {
...
},
},
{
type: 'videos',
id: '5590665282001',
attributes: {
...
},
},
{
id: '20fb845a-72ad-4d5f-a27a-c01efd857f76',
type: 'articles',
attributes: {
fn__legacy_type: 'articles',
title: 'Restaurant plans ginormous site near Wall Street, Ground Zero',
fn__media_tags: ['business'],
last_published_date: '2017-09-20T18:20:29.526Z',
thumbnail: {
image: {
url:
'https://secure.media.foxnews.com/BrightCove/990505083001/990505083001/2017/09/13/990505083001_5575086468001_5574853539001-vs.jpg?pubId=694940094001',
},
},
},
relationships: {
components_relationships: {
data: [
{
id: 'article_id_7',
type: 'videos',
},
{
id: 'article_id_8',
type: 'videos',
},
],
},
},
},
{
id: 'e6e327ec-ebb2-4220-a391-41f798e654f7',
type: 'articles',
attributes: {
...
},
relationships: {
...
},
},
{
type: 'mobile_screen_components',
id: '1_1',
attributes: { display_type: 'shelf', title: 'Featured Playlist' },
relationships: {
videos: {
data: [
[
{ type: 'videos', id: '5590720024001' },
{ type: 'videos', id: '5590670324001' },
{ type: 'videos', id: '5590665282001' },
{
id: '20fb845a-72ad-4d5f-a27a-c01efd857f76',
type: 'articles',
},
{
id: 'e6e327ec-ebb2-4220-a391-41f798e654f7',
type: 'articles',
},
],
},
articles: {
data: [
{
id: '20fb845a-72ad-4d5f-a27a-c01efd857f76',
type: 'articles',
},
{
id: 'e6e327ec-ebb2-4220-a391-41f798e654f7',
type: 'articles',
},
],
}
},
},
{
type: 'videos',
id: '1241186546001',
attributes: {
...
},
},
{
type: 'videos',
id: '1251429410001',
attributes: {
...
},
},
{
type: 'mobile_screen_components',
id: '1_2',
attributes: { display_type: 'shelf', title: 'Live TV' },
relationships: {
videos: {
data: [
{ type: 'videos', id: '1241186546001' },
{ type: 'videos', id: '1251429410001' },
],
},
},
},
{
type: 'videos',
id: '2013931500001',
attributes: {
...
},
},
{
type: 'mobile_screen_components',
id: '1_3',
attributes: { display_type: 'shelf', title: 'Live Streams' },
relationships: {
videos: {
data: [{ type: 'videos', id: '2013931500001' }],
},
},
},
],
};

对于included数组中的每个对象,我想检查它是否有"mobile_screen_components"type。如果是这样,我想获取该父对象的relationship属性中的所有对象(例如videosarticlesshows等)并抓取每个各自的data阵列。最后,所有这些数组将被连接起来,并放置在一个新的data数组下,该数组将是items数组的属性,现在是原始对象的唯一属性。

也就是说,

{
type: 'mobile_screen_components',
id: '1_1',
attributes: { display_type: 'shelf', title: 'Featured Playlist' },
relationships: {
videos: {
data: [
[
{ type: 'videos', id: '5590720024001' },
{ type: 'videos', id: '5590670324001' },
{ type: 'videos', id: '5590665282001' }
]
},
articles: {
data: [
{
id: '20fb845a-72ad-4d5f-a27a-c01efd857f76',
type: 'articles',
},
{
id: 'e6e327ec-ebb2-4220-a391-41f798e654f7',
type: 'articles',
},
],
}
},
}

会成为

{
type: 'mobile_screen_components',
id: '1_1',
attributes: { display_type: 'shelf', title: 'Featured Playlist' },
relationships: {
items: {
data: [
[
{ type: 'videos', id: '5590720024001' },
{ type: 'videos', id: '5590670324001' },
{ type: 'videos', id: '5590665282001' },
{
id: '20fb845a-72ad-4d5f-a27a-c01efd857f76',
type: 'articles',
},
{
id: 'e6e327ec-ebb2-4220-a391-41f798e654f7',
type: 'articles',
},
],
],
},
},
}

我想使用一个镜头来返回整个结构,只应用了这种转换。我最初对此的尝试不起作用:

const getMCRel = (type, rels) => {
if (type === 'mobile_screen_components' ) {
return rels
}
return undefined
} 
const findMCRel = R.compose(getMCRel, R.props(['type','relationships']));
const rLens = R.lens(findMCRel, R.assoc('relationships'));
const itemsWrapper = (arr) => ({"items": arr});
const result = R.map(R.over(rLens,R.compose(itemsWrapper, R.values)),data.included)

这并不能让你完全理解,但对于"mobile_screen_components"部分的转换,你可以使用这样的东西:

const simplify = over(
lensProp('relationships'), 
pipe(pluck('data'), values, flatten, objOf('data'), objOf('items'))
)
simplify(stuff)

你可以在Ramda REPL中看到这一点。

要测试您的物品类型是否正确,您只需使用:

propEq('type', 'mobile_screen_component')

但是你的要求对我来说还不够清楚,不知道你是否想reject那些类型不正确的,或者你是否想map并仅在这个谓词为真when应用该函数。

更新

尝试满足您的全部要求,据我所知,您可以尝试以下方法:

const simplifyAll = over(
lensProp('included'), 
map(when(propEq('type', 'mobile_screen_components'), simplify))
)
simplifyAll(data)

这在许多relationships/items/data列表中留下了很多undefined。 如果要删除它们,可以在flatten之后更新simplify以添加reject(isNil)

const simplify = over(
lensProp('relationships'), 
pipe(pluck('data'), values, flatten, reject(isNil), objOf('data'), objOf('items'))
)

您也可以在Ramda REPL中看到此版本。

最后,如果这是simplify函数的唯一用途,则可以将其内联移动。 我建议不要这样做,因为由此产生的文本墙不太可能像上述版本那样可读。 但这是你的决定。

最新更新