合并从wordpress导出的两个Json文件

And*_*son 6 wordpress merge json gatsby

我有两个JSON文件,我从wordpress导出,具有相应的ID我想将它们组合成一个Json文件,所以我可以把它带到我用Gatsby JS构建的网站.其中一个文件是posts.json,另一个是postsMeta.json.postsMeta中的post_id 与帖子中的ID相对应

我怎样才能最好地合并两者呢?我可以for在js中运行某种循环吗?我怎么会这样?我在窗户上有一些json探险家,可以帮助我做到这一点.

最后我还想修剪出一些unnecasry fiels如post_parent帖子 JSON和喜欢的东西meta_keypostsMeta JSON.

好的,希望这很清楚,提前谢谢.

以下是两个文件中第一个对象对应的示例

posts.json

{"ID":"19","post_author":"2","post_date":"2010-12-31 23:02:04","post_date_gmt":"2010-12-31 23:02:04","post_content":"Harry Potter was not available for the first sitting of the Halloween Picture. I hope everyone had a safe and fun Halloween. Tomorrow is picture retake day, please send back your previous prints if you want retakes. It is also hot lunch. See You tomorrow!","post_title":"Happy Halloween","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"open","post_password":"","post_name":"happy-halloween","to_ping":"","pinged":"","post_modified":"2011-01-03 05:26:11","post_modified_gmt":"2011-01-03 05:26:11","post_content_filtered":"","post_parent":"0","guid":"http:\/\/localhost\/mrskitson.ca_wordpress\/?p=19","menu_order":"0","post_type":"post","post_mime_type":"","comment_count":"1"},
Run Code Online (Sandbox Code Playgroud)

postsMeta.json

{"meta_id":"27","post_id":"19","meta_key":"large_preview","meta_value":"http:\/\/www.mrskitson.ca\/wp-content\/uploads\/2010\/12\/halloween.jpg"},
Run Code Online (Sandbox Code Playgroud)

更新:

是尝试使用当前答案解决此问题,您可以在那里编辑代码.

Sal*_* CJ 6

我怎样才能最好地合并两者呢?

您是否必须合并两个JSON文件/数据?

因为您可以从脚本中请求或加载JSON数据(或者甚至将它们放入HTML),然后获取特定元字段/键的元值,这function可以做到:

// `single` has no effect if `meta_key` is empty.
function getPostMeta( post_id, meta_key, single ) {
    let id = String( post_id ),
        pm = [];
    postsMeta.map( m => {
        let a = ( ! meta_key ) ||
            ( meta_key === m.meta_key );

        if ( a && id === m.post_id ) {
            pm.push( m );
        }
    });

    let meta = {},
        mk = {};
    pm.map( m => {
        let k = m.meta_key, v;

        if ( undefined === meta[ k ] ) {
            meta[ k ] = m.meta_value;
        } else {
            v = meta[ k ];
            if ( undefined === mk[ k ] ) {
                meta[ k ] = [ v ];
                mk[ k ] = 1;
            }

            meta[ k ].push( m.meta_value );
            m[ k ]++;
        }
    });

    pm = null;
    mk = meta_key ? mk[ meta_key ] : null;

    if ( mk ) {
        return single ?
            meta[ meta_key ][0] : // Returns a single meta value.
            meta[ meta_key ];     // Returns all the meta values.
    }

    return meta_key ?
        meta[ meta_key ] : // Returns the value of the `meta_key`.
        meta;              // Or returns all the post's meta data.
}
Run Code Online (Sandbox Code Playgroud)

我用于测试的数据:(注意postsMeta上面的/ getPostMeta()函数)

// Array of `post` objects.
const posts = [{"ID":"19","post_author":"2","post_date":"2010-12-31 23:02:04","post_date_gmt":"2010-12-31 23:02:04","post_content":"Harry Potter was not available for the first sitting of the Halloween Picture. I hope everyone had a safe and fun Halloween. Tomorrow is picture retake day, please send back your previous prints if you want retakes. It is also hot lunch. See You tomorrow!","post_title":"Happy Halloween","post_excerpt":"","post_status":"publish","comment_status":"open","ping_status":"open","post_password":"","post_name":"happy-halloween","to_ping":"","pinged":"","post_modified":"2011-01-03 05:26:11","post_modified_gmt":"2011-01-03 05:26:11","post_content_filtered":"","post_parent":"0","guid":"http:\/\/localhost\/mrskitson.ca_wordpress\/?p=19","menu_order":"0","post_type":"post","post_mime_type":"","comment_count":"1"}];

// Array of `meta` objects.
const postsMeta = [{"meta_id":"27","post_id":"19","meta_key":"large_preview","meta_value":"http:\/\/www.mrskitson.ca\/wp-content\/uploads\/2010\/12\/halloween.jpg"},{"meta_id":"28","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/facebook.com"},{"meta_id":"29","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/twitter.com"},{"meta_id":"30","post_id":"19","meta_key":"many_values","meta_value":"http:\/\/linkedin.com"}];
Run Code Online (Sandbox Code Playgroud)

示例:(请参阅此小提琴演示)

// In these examples, we are retrieving the meta value for the post #19 (i.e. ID is 19).

// Retrieve a single value.
// Returns mixed; string, number, etc.
let url = getPostMeta( 19, 'large_preview', true );
console.log( url );

// Retrieve all meta values.
// Always returns an array of values.
let ms = getPostMeta( 19, 'many_values' );
console.log( ms, ms[0] );

// Retrieve all meta data.
// Always returns an object with meta_key => meta_value pairs. I.e. { key => value, ... }
let ma = getPostMeta( 19 );
console.log( ma, ma.large_preview, ma.many_values[0] );
Run Code Online (Sandbox Code Playgroud)

但如果你真的必须结合JSON数据,你可以这样做:(再次,在同一个小提琴上看看demo )

// Here we modify the original `posts` object.
posts.map( p => {
    // Add all the post's meta data.
    p.meta = getPostMeta( p.ID );

    // Delete items you don't want..
    delete p.post_parent;
    delete p.menu_order;
    // delete ...;
});

console.log( JSON.stringify( posts[0].meta ) ); // posts[0].meta = object
console.log( posts[0].post_parent, posts[0].menu_order ); // both are undefined
Run Code Online (Sandbox Code Playgroud)

然后,如果要复制粘贴新的/ 合并的 JSON数据:

JSON.stringify( posts );
Run Code Online (Sandbox Code Playgroud)

但是如果你真的只想对帖子的met​​a做一些事情,你可以遍历posts对象然后做事情; 例如:

// Here the original `posts` object is not modified, and that we don't
// (though you can) repeatedly call `getPostMeta()` for the same post.
posts.map( p => {
    // Get all the post's meta data.
    let meta = getPostMeta( p.ID );

    // Do something with `meta`.
    console.log( meta.large_preview );
});

console.log( JSON.stringify( posts[0].meta ) ); // posts[0].meta = undefined
console.log( posts[0].post_parent, posts[0].menu_order ); // both still defined

// posts[0].meta wouldn't be undefined if of course posts[0] had a `meta` item,
// which was set in/via WordPress...
Run Code Online (Sandbox Code Playgroud)


Jos*_*bou 5

如果你能在js中做到这一点,那么使用它是一种非常简单的方法Array#map.如果您简化了问题,那么您真的会问如何在帖子中的每个条目下添加此元数据,并只获取您想要的字段.

我假设posts.json实际上是一个数组(例如[{"ID":"19"....).

// Load these server-side, fetch them remotely, copy-paste, etc.
// I'll require them here for simplicity
const posts = require('./posts.json');
const postsMeta = require('./postsMeta.json');

// Build a Map so we can quickly look up the metas by post_id
// Extract what we need by destructuring the args
const metaByPost = postsMeta.reduce((a, {
  post_id: id,
  meta_value: value,
}) => a.set(id, {
  value,
  /* anything else you want in here */,
}), new Map());

const mergedPosts = posts.map(post => ({
  // Spread in the post
  ...post,
  // Spread in the meta content
  ...metaByPost.get(post.ID),
  // Undefine the props we don't want
  post_parent: undefined,
}));
Run Code Online (Sandbox Code Playgroud)

我不喜欢手动设置未定义的东西 - 我认为明确说出你要包含的道具更好,而不是加载所有东西并取消定义某些道具.


atm*_*min 5

直接在Chrome DevTools控制台中试用此代码段:

(function(
  postsUrl='https://cdn.glitch.com/61300ea6-6cc4-4cb6-a62f-31adc62ea5cc%2Fposts.json?1525386749382',
  metaUrl='https://cdn.glitch.com/61300ea6-6cc4-4cb6-a62f-31adc62ea5cc%2Fpostmeta.json?1525386742630'
) {
  Promise.all([
    fetch(postsUrl).then(r => r.json()),
    fetch(metaUrl).then(r => r.json()),
  ]).then(([postsResponse, metaResponse]) => {
    // Inspected the actual JSON response to come up with the data structure
    const posts = postsResponse[2].data;
    const meta = metaResponse[2].data;
    const metaByPostId = meta.reduce((accum, el) => {
      accum[el.post_id] = el;
      return accum;
    }, {});
    const transformedPosts = posts.map(post => {
      const merged = {
        ...post,
        ...(metaByPostId[post.ID] || {}),
      };
      delete merged.post_parent;
      // delete any other fields not wanted in the result
      return merged;
    });
    console.log(transformedPosts);
  });
})();
Run Code Online (Sandbox Code Playgroud)
  • 相应地替换URL,我使用了来自Glitch示例的URL
  • 如评论所述,实际数据被埋没在内response[2].data.使用"网络"选项卡/"解析"视图查看结构
  • 更换console.logcopy,如果你想复制到剪贴板的结果,而不是记录到控制台


Att*_*son 2

直截了当地回答你的问题。我们想:

\n\n
    \n
  • 合并var a = {/*some json*/}var b = {/*another json*/}
  • \n
  • 修剪字段var exclusions = ["post_parent","meta_key"]
  • \n
\n\n

合并 JSONS

\n\n

首先,我们需要填充 a 和 b。\n您的 JSON 可以使用JSON.parse()解析为 Javascript 对象:

\n\n
let a = JSON.parse(/*JSON here*/);\nlet b = JSON.parse(/*JSON here*/);\n
Run Code Online (Sandbox Code Playgroud)\n\n

因为属性是在 Javascript 中定义的,如果再次定义属性,第二个定义将覆盖第一个。您的 JSON 仅包含字符串作为键和字符串作为值,因此浅拷贝就足够了。Object.assign()会将所有属性(字段和值)复制到第一个参数中并返回最终对象。因此,这会将 a 合并到 b 中,假设它们具有不同的键,否则 b 中的值将覆盖 a 中的值:

\n\n
a = Object.assign(a,b);\n
Run Code Online (Sandbox Code Playgroud)\n\n

否则,如果它们不相交,您必须定义一些关于如何加入的策略,例如可以优先考虑其中一个。下面,我们将值保留在 a 中:

\n\n
a = Object.assign(b,a);\n
Run Code Online (Sandbox Code Playgroud)\n\n

由于您提到了for循环,因此下面的行与上面的两行代码的作用相同,并且还允许向您展示如何编写自己的自定义 lambda 表达式的示例:

\n\n
Object.keys(a).forEach(k=>b[k]=b[k]?b[k]:a[k]);\n
Run Code Online (Sandbox Code Playgroud)\n\n

不想碰ab?创建第三个对象c

\n\n
let c = Object.assign({},a,b)\n
Run Code Online (Sandbox Code Playgroud)\n\n

最后(等到下面的修剪步骤完成)JSON.stringify()会将合并的对象转换回 JSON。

\n\n

修剪排除项

\n\n

按照第三个示例,我们c合并了所有字段。

\n\n

首先从这里获取一些小技巧:

\n\n
Object.filter = (obj, predicate) => Object.keys(obj)\n    .filter( key => predicate(obj[key]))\n    .reduce( (res, key) => (res[key] = obj[key], res), {} );\n
Run Code Online (Sandbox Code Playgroud)\n\n

现在对象,就像数组有一个过滤器原型一样,有扩展的对象原型。这并不是真正的最佳实践,因为这会扩展每个对象,但这个函数在 Javascript 语义方面工作得很好,这个例子可以作为保持优雅 Javascript 样式代码的机会:

\n\n
c = Object.filter(c, key=> !exclusions.includes(key) );\n
Run Code Online (Sandbox Code Playgroud)\n\n

Voit -l\xc3\xa1,完成。

\n\n

至于定义的 Object.filter() 它使用Array.filter( ) 和Array.reduce()。点击查看,方便您参考。

\n