Используйте функцию map для создания одного массива из Object, в котором есть массивы

1

Используя Javascript, я пытаюсь создать один массив из объекта JSON. Проблема в том, что я пытаюсь получить acceptAnswers, который является массивом. Я полагал, что карта была лучшей функцией для этого. Однако возвращаемый массив представляет собой массив массивов. Я хочу получить только массив значений. Спасибо за вашу помощь.

Код

let categories = [
      {
        "categoryID": "1",
        "categoryName": "Fruits with seeds",
        "acceptedAnswers": [
          "2","5"
        ]
      },
      {
        "categoryID": "2",
        "categoryName": "Fruits without seeds",
        "acceptedAnswers": [
          "1","3","4"
        ]
      },
      {
        "categoryID": "3",
        "categoryName": "Blue Fruit",
        "acceptedAnswers": [
          "1"
        ]
      }
    ]

JS

let catAcceptedAnswerArray = categories.map(function (cat) {
 return cat.acceptedAnswers
})
console.log(catAcceptedAnswerArray)

Возвращает:

0: ["2","5"]
1: ["1","3","4"]
2: ["1"]

Я пытаюсь вернуться:

0: ["2","5","1","3","4","1"]

Вот скрипка

Теги:
arrays

3 ответа

4
Лучший ответ

map не является подходящим инструментом для достижения здесь. Просто создайте массив и добавьте в него все записи объекта:

const result = [];
for (const category of categories) {
    result.push(...category.acceptedAnswers);
}

Или если вы не можете использовать функции ES2015+, версию ES5:

var result = [];
categories.forEach(function(category) {
    result.push.apply(result, category.acceptedAnswers);
});

Это предполагает, что не будет тысяч и тысяч acceptedAnswers; один вызов push имеет ограничения для конкретной платформы (но опять же, они в тысячах).

Как и почти все операции с массивами, это позволяет reduce, но вы ничего не получаете от него:

var result = categories.reduce(function(arr, category) {
    arr.push.apply(arr, category.acceptedAnswers);
    return arr;
}, []);
  • 0
    У тебя есть мой меч.
  • 0
    @hsz LOL :-) ....
Показать ещё 1 комментарий
2

С ES6 вы можете попробовать:

categories
  .map(category => category.acceptedAnswers)
  .reduce((acc, ids) => acc.concat(ids), [])
  • 1
    Это ужасно неэффективно, но да, вы можете. :-)
  • 1
    Слегка :-) concat тоже создает новый массив. Здесь нет необходимости в каких-либо временных массивах.
1

Вы можете просто уменьшить массив до первого уровня после сопоставления с помощью Array#concat

let categories = [{
    "categoryID": "1",
    "categoryName": "Fruits with seeds",
    "acceptedAnswers": [
      "2", "5"
    ]
  },
  {
    "categoryID": "2",
    "categoryName": "Fruits without seeds",
    "acceptedAnswers": [
      "1", "3", "4"
    ]
  },
  {
    "categoryID": "3",
    "categoryName": "Blue Fruit",
    "acceptedAnswers": [
      "1"
    ]
  }
]

let catAcceptedAnswerArray = categories.map(cat => cat.acceptedAnswers).reduce((acc, val) => acc.concat(val), []);

console.log(catAcceptedAnswerArray)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню