javascript - Turn array of comma delimited strings into distinct array - Stack Overflow

I would like to take an array of objects:var objArr = [{id:1, name:'test', seenby:'user1

I would like to take an array of objects:

var objArr = [
    {id:1, name:'test', seenby:'user1, user2, user3'},
    {id:2, name:'test1', seenby:'user3, user4'},
    {id:3, name:'test2', seenby:'user1, user3'},
    {id:4, name:'test3', seenby:'user2'}
];

And return a distinct array of all 'seenby' users:

var seenByArr = ['user1', 'user2', 'user3', 'user4']

I can't figure out how to efficiently (fewest lines possible) turn this into an array of distinct values. Please check out my fiddle for an example: /

I would like to take an array of objects:

var objArr = [
    {id:1, name:'test', seenby:'user1, user2, user3'},
    {id:2, name:'test1', seenby:'user3, user4'},
    {id:3, name:'test2', seenby:'user1, user3'},
    {id:4, name:'test3', seenby:'user2'}
];

And return a distinct array of all 'seenby' users:

var seenByArr = ['user1', 'user2', 'user3', 'user4']

I can't figure out how to efficiently (fewest lines possible) turn this into an array of distinct values. Please check out my fiddle for an example: https://jsfiddle/ksumarine/ss3v7dgj/

Share Improve this question asked Feb 16, 2016 at 19:11 ksumarineksumarine 7822 gold badges13 silver badges33 bronze badges 2
  • Premature optimization is the root of all evil -- DonaldKnuth – Michael Hobbs Commented Feb 16, 2016 at 19:17
  • Agreed, unfortunately that's the data I have to work with :/ – ksumarine Commented Feb 16, 2016 at 19:20
Add a ment  | 

6 Answers 6

Reset to default 3

I realize this question doesn't mention Underscore, but it's worth mentioning that Underscore.js is a very popular library for manipulating objects and arrays, and well-suited for this kind of thing.

Here's a big unreadable single line for achieving this with Underscore:

_.unique(_.flatten(_.map(_.pluck(objArr, 'seenby'), function(seenby) { return seenby.split(', '); })))

The laconic solution with String.split and Array.foreach functions:

var arr = [];
objArr.forEach(function (obj) {
        var str = obj.seenby.split(',');
        str.forEach(function (v) {
            var user = v.trim();
            if (arr.indexOf(user) === -1) arr.push(user);
        });
});

console.log(arr);
// the output:
["user1", "user2", "user3", "user4"]    

You can try following

$.each(list, function(index, value) {
    $.each(value.seenby.split(","), function(i, val) {
        if (val !== undefined && val.trim() !== "" && arr.indexOf(val.trim()) == -1) {
            arr.push(val.trim());
        }
    });
});

For reference - https://jsfiddle/ss3v7dgj/1/

A solution in plain Javascript with an IIFE and a temporary object for the items.

var objArr = [{ id: 1, name: 'test', seenby: 'user1, user2, user3' }, { id: 2, name: 'test1', seenby: 'user3, user4' }, { id: 3, name: 'test2', seenby: 'user1, user3' }, { id: 4, name: 'test3', seenby: 'user2' }],
    result = function (array) {
        var obj = {}, r = [];
        array.forEach(function (a) {
            a.seenby.split(', ').forEach(function (b) {
                obj[b] = obj[b] || r.push(b);
            });
        });
        return r;
    }(objArr);

document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

given = function (x) {
    return {
        do: function (f) { x = f(x); return this },
        return: function () { return x }
    }
};

r = given(objArr)
    .do(x => x.map(y => y.seenby))
    .do(x => [].concat.apply([], x))
    .do(x => x.join(', '))
    .do(x => x.split(', '))
    .do(x => x.filter((e, i) => x.indexOf(e) === i))
    .do(x => x.sort())
    .return();

I might find use for this someday...

I would use the Array.prototype.map function, and de-duplicate the users in a associative array. So here the interesting part, but you can also try it out here:

var list = [
    {id:1, name:'test', seenby:'user1, user2, user3'},
    {id:2, name:'test1', seenby:'user3, user4'},
    {id:3, name:'test2', seenby:'user1, user3'},
    {id:4, name:'test3', seenby:'user2'}
];

var arr = [];
list.map(function(value){
        value.seenby.split(",").map(function(val){
      arr[val.trim()] = 1;
        });
});

var seenby = Object.keys(arr);

How does it work? The map function will iterate over all the list items, the next map will iterate over all the seenby items. We then collect the users in the arr, de-duplicating by using it as an associative array. At the end we extract all the associative array keys by using the Object.keys function.

Minor caveat is that this solution will only work if the map function exists, if it doesn't you would need to implement it yourself. But usually you are using a new enough JavaScript version that does support it. This solution also has the nice side effect that you don't really need any external dependency (except of course for displaying it)

UPDATE: I think it's actually better to do it the following way:

var arr = list
    .reduce(function(acc, value){
        return acc.concat(value.seenby.split(",").map(function(val){
            return val.trim()
    }))},[])
    .filter(function(item, index, array) {
        return array.indexOf(item) === index
    }
)

Explanation:

  • we take the list and for each item, we reduce it ...
    • from each item, we extract the seenby field
    • we split the field
    • we map each item to trim it
  • ... we take the array of returned seenby and concatenate them to our accumulator array arr (which is initialized as empty array [])
  • then we filter out the duplicates from the array (by checking whether the index of an item is the same as the current index)

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744825609a4595775.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信