В настоящее время я пытаюсь получить список метаданных, хранящихся в виде массива, внутри объекта, внутри массива. Вот лучший пояснительный пример:

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

Теперь моя цель - получить список метаданных (по их имени) без избыточности. Я думаю, что .map () является ключом к успеху, но я не могу найти, как это сделать кратко, на самом деле мой код составлен 2 для и 3, если, и я чувствую себя грязно, чтобы сделать это.

Ожидаемый ввод: ['Author', 'Creator', 'Created', 'Date']

Я разрабатываю в Typescript, если это может помочь для какой-то функции.

2
Sakuto 8 Дек 2016 в 16:35

4 ответа

Лучший ответ

Вы можете использовать reduce(), а затем map(), чтобы вернуть массив имен.

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)
3
Nenad Vracar 8 Дек 2016 в 14:07

Вы можете использовать Set для уникальных имен.

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; }
2
Nina Scholz 8 Дек 2016 в 13:43

Рукопашная Array.prototype.reduce() и Array.prototype.map() должны сделать это следующим образом;

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);
1
Redu 8 Дек 2016 в 17:28
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})
1
Filipe Roberto 8 Дек 2016 в 13:51