5

I am still learning JavaScript, so I apologize in advance if this seems a remedial question.

I am receiving data from an API call in the form of an array, like so:

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

Though it's not evident from that array, the number following each topic string is the count of the previous topic.

I want to work with this data in a React app, i.e., map it to a table or other data structure. But that's exceedingly difficult to do when the values are anonymous like this.

So, I want to take this array and convert it into an object with key/value pairs. So, after working some kind of loop/filter/map/etc. on the array, I need to end up with this:

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

I have tried SO many techniques, ranging from using dictionaries, Maps, map, filter, forEach, for ... in, and more techniques than I even remember at this point. And yes, I searched many web pages and forums. The problem is, my question includes some of the very building blocks of JavaScript, so the answers I found were never specific enough for my problem.

I did successfully filter out the even and odd elements in the array, like so:

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
});

But I've never successfully gotten the result I need. Can anybody please help point me in the right direction?

I'm using React, so feel free to suggest modern JS techniques. Thanks!

6
  • 1
    Because you are a new user, a useful advice for you: arrays and objects are used in many languages. So please add a properly language tag to your question (I did it for you at this one). Commented Feb 27, 2018 at 15:08
  • If both arrays are equal, loop them and create an object out of it and add to an array! Commented Feb 27, 2018 at 15:08
  • 1
    Possible duplicate of Is it possible to add dynamically named properties to JavaScript object? Commented Feb 27, 2018 at 15:12
  • 1
    Thanks, reporter...good to know! Bharadwaj, I think I get that, but there is only a single array consisting of topic, count, topic, count, etc. So, there is an association between each pair of items. By combining two filtered arrays this way, can I be sure the resulting object maintains the correct relationship in the correct order? Commented Feb 27, 2018 at 15:12
  • 1
    GalAbra, if it is a duplicate, I can't make heads nor tails of that other post. :) What I have going for me in this instance is that the array structure I'm getting back from the API never changes...only the data does. So, I need some kind of function to take that data, however long or short the array, and map each element to either "topic" or "count", as the case may be. I never need to dynamically add or remove properties. I make the call, get the array, perform the conversion. I then have a nice object I can map to a table or whatever I want. Commented Feb 27, 2018 at 15:16

3 Answers 3

5

You need to loop through your API response and build the objects from the array.

let objectArray = []

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

I'm sure there's an easier way to do it, but this will get you what you need.

See it in action on jsFiddle: https://jsfiddle.net/L6023fn6/1/

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

1 Comment

Thank you so much!! That is exactly what I was trying to do. Shocking how simple it actually was! I have a lot to learn...
1

You can use array.reduce for this which takes an array and emits an aggregated value, array, object, or something else. A full implementation would be:

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;
}, []);

If you're willing to use an external library like lodash you can make this even easier since it will chunk the array for you.

const newArr = _.zipWith(_.chunk(arr, 2), a => ({ topic: a[0], count: a[1] }));

1 Comment

The "for loop" solution above actually gets me what I needed. Thanks for your help, though!
0

From your question, the arr is a string,number... pattern, going by that i feel you can do this.

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;

}

Comments

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.