将价值推入对象

时间:2019-05-20 00:52:54

标签: javascript

我有以下

const post = [
    { postTitle: 'Title1', key: 'key1' },
    { postTitle: 'Title2', key: 'key2' }
];

const comment = [
    { key: 'key1', c: 'comment1' },
    { key: 'key1', c: 'comment2' },
    { key: 'key2', c: 'commentA' },
    { key: 'key2', c: 'commentB' },
    { key: 'key2', c: 'commentC' }
];

最后我得到以下结果:

const newPost = [
    {
        postTitle: 'Title1',
        key: 'key1',
        comment: ['comment1', 'comment2']
    },
    {
        postTitle: 'Title2',
        key: 'key2',
        comment: ['commentA', 'commentB', 'commentC']
    }
];

以下代码似乎几乎可以完成工作,但是它覆盖了我的注释。我只得到每个postTitle的最新评论。我该如何修复代码或改进代码以完全像上面的结果一样?

这是有问题的代码:

for (var i = 0; i < post.length; ++i) {
    for (var j = 0; j < comment.length; j++) {
        if (post[i].key === comment[j].key) {
            post[i].comment = [];
            post[i].comment.push([comment[j].c]);
        } else {
            console.log('no comment to add');
        }
    }
}

此外,如果有更优雅的重构代码,请在此处共享。谢谢。

5 个答案:

答案 0 :(得分:1)

问题

正如您所指出的,代码的问题是您覆盖了注释数组。问题出在这里:

post[i].comment = [];

仅当数组不存在时才执行以上行 ,而不是每次执行。

使用简单的条件检查替换上面的行即可:

if (!post[i].comment) post[i].comment = [];

const post = [{postTitle : 'Title1', key: 'key1'},{postTitle : 'Title2', key: 'key2'}];
const comment = [{key : 'key1', c: "comment1"},{key : 'key1', c: "comment2"},{key : 'key2', c: "commentA"},{key : 'key2', c: "commentB"},{key : 'key2', c: "commentC"}];

for (var i = 0; i < post.length; ++i) {
  for (var j = 0; j < comment.length; j++) {
    if (post[i].key === comment[j].key) {
      if (!post[i].comment) post[i].comment = [];
      post[i].comment.push([comment[j].c]);
    } else {
      console.log('no comment to add');
    }
  }
}

console.log(post);


建议的重构

我将map()用于外部迭代,将reduce()用于内部迭代。

内部reduce()检索相关注释并将它们作为数组返回。外部.map()将这些注释作为属性添加到post中(并将修改后的帖子作为新数组返回)。

const post = [{postTitle : 'Title1', key: 'key1'},{postTitle : 'Title2', key: 'key2'}];
const comments = [{key : 'key1', c: "comment1"},{key : 'key1', c: "comment2"},{key : 'key2', c: "commentA"},{key : 'key2', c: "commentB"},{key : 'key2', c: "commentC"}];

const result = post.map(post => {

  post.comments = comments.reduce((out,comment) => {    //Optimized .filter() + .map()
    if (comment.key === post.key) out.push(comment.c); 
    return out;
  }, []);
  
  return post;

});
  
console.log(result);

为了解决前面的评论,尽管我相信.filter() + .map()会导致代码看起来更简洁,但我选择使用.reduce()来组合它们。这仅仅是为了提高效率;我更喜欢一个内循环而不是两个。

答案 1 :(得分:1)

稍有不同的方法将注释扫描一次,然后将它们组合在一起,然后使用生成的对象作为映射帖子的查找:

const combine = (posts, comments) => {
  const keyedComments = comments .reduce (
    (a, {key, c}) => (a [key] = (a [key] || [] ) .concat(c), a),
    {}
  )
  return posts .map ( ({key, ...rest}) => ({
    ...rest, 
    comment: keyedComments [key] || []
  }))
}

const post = [{postTitle : 'Title1', key: 'key1'}, {postTitle : 'Title2', key: 'key2'}]
const comment = [{key : 'key1', c: "comment1"}, {key : 'key1', c: "comment2"}, {key : 'key2', c: "commentA"}, {key : 'key2', c: "commentB"}, {key : 'key2', c: "commentC"}]

console .log (
  combine (post, comment)
)

答案 2 :(得分:0)

您快到了,我在代码中添加了注释,以说明问题所在。

post = [
    {postTitle: 'Title1', key: 'key1'},
    {postTitle: 'Title2', key: 'key2'}
];

comment = [
    {key: 'key1', c: "comment1"},
    {key: 'key1', c: "comment2"},
    {key: 'key2', c: "commentA"},
    {key: 'key2', c: "commentB"},
    {key: 'key2', c: "commentC"}
];

for (var i = 0; i < post.length; ++i) {
  for (var j = 0; j < comment.length; j++) {
    if (post[i].key === comment[j].key) {
      // Only set post[i].comment = [] when it is undefined (Only when the first comment is being added)
      if (typeof post[i].comment === 'undefined') {
        post[i].comment = [];
      }
      // Push only the comment, instead of [comment[j].c]
      post[i].comment.push(comment[j].c);
    } else {
      console.log('no comment to add');
    }
  }
}

console.log('post:', post);
console.log('comment:', comment);

另一种方法:

使用Array.find获取与此评论相关的信息,然后我们Array.isArray检查post.comments是否已经存在,推送它,否则创建post.comments键< / p>

posts = [
    {postTitle: 'Title1', key: 'key1'},
    {postTitle: 'Title2', key: 'key2'}
];

comments = [
    {key: 'key1', c: "comment1"},
    {key: 'key1', c: "comment2"},
    {key: 'key2', c: "commentA"},
    {key: 'key2', c: "commentB"},
    {key: 'key2', c: "commentC"}
];

result = comments.map((comment) => {
  let post = posts.find(o => o.key === comment.key);
  Array.isArray(post.comments) ? post.comments.push(comment.c) : post.comments = [comment.c];
});

console.log('posts', posts);
console.log('comments', comments);

答案 3 :(得分:0)

您可以使用mapfilter函数来获得所需的结果

请尝试以下示例

const post = [
    { postTitle: 'Title1', key: 'key1' },
    { postTitle: 'Title2', key: 'key2' }
];

const comment = [
    { key: 'key1', c: 'comment1' },
    { key: 'key1', c: 'comment2' },
    { key: 'key2', c: 'commentA' },
    { key: 'key2', c: 'commentB' },
    { key: 'key2', c: 'commentC' }
];

const newPost = [
    {
        postTitle: 'Title1',
        key: 'key1',
        comment: ['comment1', 'comment2']
    },
    {
        postTitle: 'Title2',
        key: 'key2',
        comment: ['commentA', 'commentB', 'commentC']
    }
];

const result = post.map(p => {
    const obj = Object.assign({}, p);

    obj.comment = comment.filter(c => c.key === p.key).map(c => c.c);

    return obj;
});

console.log(result);

答案 4 :(得分:0)

之所以只得到每个postTitle的最后一条评论,是因为该if语句

        if (post[i].key === comment[j].key) {
            // each time the post[i].key === comment[j].key
            // the line below is resetting the post[i].comment array to an
            // empty array
            post[i].comment = [];
            post[i].comment.push([comment[j].c]);
        }

您应该改写

for (var i = 0; i < post.length; ++i) {
    for (var j = 0; j < comment.length; j++) {
        if (post[i].key === comment[j].key) {
         // line below will check if there isn't a post[i].comment array 
         // declared yet
         if (!post[i].comment){
            post[i].comment = [];
         }
           post[i].comment.push(comment[j].c);
        }
        else {
        console.log('no comment to add');        }
    }
}

希望这会有所帮助。