如何从对象数组中获取数组本身的属性的所有唯一值

时间:2018-06-26 17:04:12

标签: javascript arrays filter unique

This answer is already close,对于如何在数组中获取唯一值(删除重复项),有一些答案,尽管在涉及对象数组和属性的情况下,我无法使其工作应该过滤的是一个数组。抱歉,我是JS新手。感谢您的帮助。

我有一个这样的对象数组

const posts = [
  post1: {
    id: 1,
    title: 'One',
    tags: ['tagA', 'tagB']
    },
  post2: {
    id: 2,
    title: 'Two',
    tags: ['tagB', 'tagC']    
    },
  post3: {
    id: 3,
    title: 'Three',
    tags: ['tagB', tagC, tagD]    
    ]

我需要的是所有唯一标签的数组...在上述情况下,预期输出如下:

// [tagA, tagB, tagC, tagD] 

编辑/更新

对象数组中的键用于管理react组件的状态...例如

constructor(props) {
super(props);

this.state = {
  posts: []
};
}

...

updatePost = (key, updatedPost) => {
//1. Take copy of the current this.state.
const posts = {...this.state.texts};
//2. Update that state
posts[key] = updatedPost;
//3. Set that to state
const options = { encrypt: false }
putFile(postsFileName, JSON.stringify(posts), options)
  .then(() => {
    this.setState({
      posts: posts
    })
  })
  };

5 个答案:

答案 0 :(得分:3)

假设输入为[ {} , {} ]格式:

您可以使用concatmap来展平数组。使用new Set获取唯一值。

const posts = [{"id":1,"title":"One","tags":["tagA","tagB"]},{"id":2,"title":"Two","tags":["tagB","tagC"]},{"id":3,"title":"Three","tags":["tagB","tagC","tagD"]}];

var result = [...new Set([].concat(...posts.map(o => o.tags)))];

console.log(result);


如果变量是对象({a:{} , b:{} }),则可以使用Object.values将对象转换为数组。

const posts = {"post1":{"id":1,"title":"One","tags":["tagA","tagB"]},"post2":{"id":2,"title":"Two","tags":["tagB","tagC"]},"post3":{"id":3,"title":"Three","tags":["tagB","tagC","tagD"]}}

var result = [...new Set([].concat(...Object.values(posts).map(o => o.tags)))];

console.log(result);

答案 1 :(得分:0)

您可以reduce遍历您的帖子并遍历标签,然后将其推送到您尚未遇到的结果上:

const posts = [
  {
    id: 1,
    title: "One",
    tags: ["tagA", "tagB"]
  },
  {
    id: 2,
    title: "Two",
    tags: ["tagB", "tagC"]
  },
  {
    id: 3,
    title: "Three",
    tags: ["tagB", "tagC", "tagD"]
  }
];

const uniqueTags = posts.reduce((result, post) => {
  post.tags.forEach(tag => {
    if (!result.includes(tag)) {
      result.push(tag);
    }
  });

  return result;
}, []);

console.log(uniqueTags);

答案 2 :(得分:0)

这是假设您知道阵列键始终是“标签”。

let filter = {};
let result = [];

posts.forEach(post => {
  const tags = post['tags'];
  tags.forEach(tag => {
    if (!filter.hasOwnProperty(tag)) {
      result.push(tag);
      filter[tag] = true; 
    }
  });
});

答案 3 :(得分:0)

使用jquery,您可以执行以下操作(未测试):

var results = [];
$.each(myObject, function(key,valueObj){
    var check.isArray(obj);
    if(check){
        alert(key + "/" + valueObj );
        /*replace repeat*/
        var sorted_check = check.slice().sort(); // You can define the comparing function here. 
                                     // JS by default uses a crappy string compare.
                                     // (we use slice to clone the array so the
                                     // original array won't be modified)

        for (var i = 0; i < sorted_check.length - 1; i++) {
            if (sorted_check[i + 1] == sorted_check[i]) {
                results.push(sorted_check[i]);
            }
        }
    }
});

和indexof的好方法:

Array.prototype.unique = function() {
    var a = [];
    for ( i = 0; i < this.length; i++ ) {
        var current = this[i];
        if (a.indexOf(current) < 0) a.push(current);
    }

    this.length = 0;
    for ( i = 0; i < a.length; i++ ) {
        this.push( a[i] );
    }

    return this;
}

Array.prototype.unique = function() {
    var a = [];
    for ( i = 0; i < this.length; i++ ) {
        var current = this[i];
        if (a.indexOf(current) < 0) a.push(current);
    }
    return a;
}

然后继续:

Array.prototype.unique = function(mutate) {
    var unique = this.reduce(function(accum, current) {
        if (accum.indexOf(current) < 0) {
            accum.push(current);
        }
        return accum;
    }, []);
    if (mutate) {
        this.length = 0;
        for (let i = 0; i < unique.length; ++i) {
            this.push(unique[i]);
        }
        return this;
    }
    return unique;
}

答案 4 :(得分:0)

如果要使用Ramda.js之类的功能库,可以执行以下操作:

const posts = [
	{
		id: 1,
		title: 'One',
		tags: ['tagA', 'tagB'],
	},
	{
		id: 2,
		title: 'Two',
		tags: ['tagB', 'tagC'],
	},
	{
		id: 3,
		title: 'Three',
		tags: ['tagB', 'tagC', 'tagD'],
	},
];

var unique = R.uniq(R.flatten(R.map(R.prop('tags'), posts)))
console.log(unique)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script>