2

I'm currently trying to retrieve a list of metadata stored as an array, inside an object, inside an array. Here's a better explanatory example:

[
    {
        name: 'test',
        metadata: [
            {
                name: 'Author',
                value: 'foo'
            },
            {
                name: 'Creator',
                value: 'foo'
            }
        ]
    },
    {
        name: 'otherTest',
        metadata: [
            {
                name: 'Created',
                value: 'foo'
            },
            {
                name: 'Date',
                value: 'foo'
            }
        ]
    },
    {
        name: 'finalTest'
    }
]

Now, my objective is to retrieve a list of metadata (by their name) without redundancy. I think that .map() is the key to success but I can't find how to do it in a short way, actually my code is composed 2 for and 3 if, and I feel dirty to do that.

The expected input is: ['Author', 'Creator', 'Created', 'Date']

I'm developping in Typescript, if that can help for some function.

4
  • what do you need from metadata? the whole object or just parts? Commented Dec 8, 2016 at 13:37
  • Only the name. Will edit the first post Commented Dec 8, 2016 at 13:38
  • 2
    What is your desired output for the above input? Commented Dec 8, 2016 at 13:41
  • ['Author', 'Creator', 'Created', 'Date'] Commented Dec 8, 2016 at 13:43

4 Answers 4

3

You can use reduce() and then map() to return array of names.

var data = [{"name":"test","metadata":[{"name":"Author","value":"foo"},{"name":"Creator","value":"foo"}]},{"name":"otherTest","metadata":[{"name":"Created","value":"foo"},{"name":"Date","value":"foo"}]},{"name":"finalTest"}]

var result = [...new Set(data.reduce(function(r, o) {
  if (o.metadata) r = r.concat(o.metadata.map(e => e.name))
  return r
}, []))];


console.log(result)

Sign up to request clarification or add additional context in comments.

2 Comments

it looks, you concat any name, you get in the array, without checking for uniqueness.
@Nina Scholz Yea my bad, fixed it.
2

You could use Set for unique names.

var data = [{ name: 'test', metadata: [{ name: 'Author', value: 'foo' }, { name: 'Creator', value: 'foo' }] }, { name: 'otherTest', metadata: [{ name: 'Created', value: 'foo' }, { name: 'Date', value: 'foo' }] }, { name: 'finalTest' }],
    names = new Set;

data.forEach(a => (a.metadata || []).forEach(m => names.add(m.name)));

console.log([...names]);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

1
var data = [{"name":"test","metadata":[{"name":"Author","value":"foo"},{"name":"Creator","value":"foo"}]},{"name":"otherTest","metadata":[{"name":"Created","value":"foo"},{"name":"Date","value":"foo"}]},{"name":"finalTest"}]

data
.filter(function(obj){return obj.metadata != undefined})
.map(function(obj){return obj.metadata})
.reduce(function(a,b){return a.concat(b)},[])
.map(function(obj){return obj.name})

Comments

1

A hand to hand Array.prototype.reduce() and Array.prototype.map() should do it as follows;

var arr = [
    {
        name: 'test',
        metadata: [
            {
                name: 'Author',
                value: 'foo'
            },
            {
                name: 'Creator',
                value: 'foo'
            }
        ]
    },
    {
        name: 'otherTest',
        metadata: [
            {
                name: 'Created',
                value: 'foo'
            },
            {
                name: 'Date',
                value: 'foo'
            }
        ]
    },
    {
        name: 'finalTest'
    }
];

result = arr.reduce((p,c) => c.metadata ? p.concat(c.metadata.map(e => e.name))
                                        : p, []);
console.log(result);

2 Comments

It seems to not work anymore in my typescript code, is it related to a new update or something?
There are some type coercions going on tin this snippet such as c.metadata ? ... I am not sure if you can do these in TypeScript. From the name i suspect it must be strict on types. Did it ever work with TypeScript and now stopped working?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.