Я все еще изучаю JavaScript, поэтому заранее прошу прощения, если это кажется исправительным вопросом.

Я получаю данные от вызова API в виде массива, например так:

arr = ['topic1',497,'topic2',591,'topic3',17,'topic4',980]

Хотя это не очевидно из этого массива, число после каждой строки темы - это счет предыдущей темы.

Я хочу работать с этими данными в приложении React, то есть сопоставить их с таблицей или другой структурой данных. Но это чрезвычайно трудно сделать, когда значения анонимны, как это.

Итак, я хочу взять этот массив и преобразовать его в объект с парами ключ / значение. Итак, после работы какой-то цикл / фильтр / карта / и т.д. в массиве мне нужно в конечном итоге это:

newArr = [
  {topic: 'topic1', count: 497},
  {topic: 'topic2', count: 591},
  {topic: 'topic3', count: 17},
  {topic: 'topic4', count: 980},
]

Я испробовал ОЧЕНЬ много техник, начиная от использования словарей, карт, карт, фильтров, forEach, for ... in, и больше техник, которые я даже не помню на данный момент. И да, я искал много веб-страниц и форумов. Проблема в том, что мой вопрос включает в себя некоторые из самых строительных блоков JavaScript, поэтому ответы, которые я нашел, никогда не были достаточно конкретными для моей проблемы.

Я успешно отфильтровал четные и нечетные элементы в массиве, вот так:

let x = arr.filter((element, index) => {
  return index % 2 === 0; filter elements located at an even index
});

let y = arr.filter((element, index) => {
  return index % 2 === 1; filter elements located at an odd index
});

Но я так и не получил результат, который мне нужен. Кто-нибудь может помочь, пожалуйста, указать мне правильное направление?

Я использую React, поэтому не стесняйтесь предлагать современные методы JS. Благодарность!

3
patrickrs 27 Фев 2018 в 18:03

3 ответа

Лучший ответ

Вам нужно перебрать свой ответ API и построить объекты из массива.

let objectArray = []

for(let i = 0; i < arr.length - 1; i+=2){
    objectArray.push({"topic": arr[i], "count": arr[i+1]})
}

Я уверен, что есть более простой способ сделать это, но это даст вам то, что вам нужно.

Посмотрите это в действии на jsFiddle: https://jsfiddle.net/L6023fn6/1/

4
Mario Murrent 27 Фев 2018 в 15:23

Исходя из вашего вопроса, arr - это шаблон строка, число ... , который, я думаю, вы можете сделать это.

const arr = ['topic1',497,'topic2',591,'topic3',17,'topic4',980];
const result = [];

for(let i=0; i<arr.length; i+=1) {
 typeof arr[i] === 'string' 
 ?
  result.push({topic: arr[i], count: arr[i+1]})
:
null;

}

0
Balogun Abbey 27 Фев 2018 в 15:49

Вы можете использовать array.reduce для этого, который принимает массив и генерирует агрегированное значение, массив, объект или что-то еще. Полная реализация будет:

const newArr = arr.reduce((fonts, value, index) => {
   if (0 === index % 2) {
     fonts.push({ topic: value });
   } else {
     // output array will be half the size of the input hence the / 2
     fonts[Math.ceil(index / 2 - 1)].count = value;
   }

   return fonts;
}, []);

Если вы хотите использовать внешнюю библиотеку, такую как lodash, вы можете сделать это еще проще, поскольку она будет разбивать массив на части для вас.

const newArr = _.zipWith(_.chunk(arr, 2), a => ({ topic: a[0], count: a[1] }));
1
Explosion Pills 27 Фев 2018 в 15:18