# Working vs Elegant/Efficient

**URL:** <https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896>\
**Category:** General\
**Created:** [July 4, 2017, 3:11am UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896 "2017-07-04T03:11:57Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![alightedlamp](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/alightedlamp/32/63336_2.png) [@alightedlamp](https://forum.freecodecamp.org/u/alightedlamp)\
**Post date:** [July 4, 2017, 3:11am UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/1 "2017-07-04T03:11:58Z")

</div>

I’m working on the Wikipedia Viewer, and have been beating my head against the wall trying to get the API response converted into an array of objects I can loop over to display on the page.

Their API gives me something like this:

`[[title1, title2, title3], [summary1, summary2, summary3], [link1, link2, link3]]`

I want to make this an object with keys so it’s easier to display the results. I’ve got a working solution, but it’s not very elegant:

```
  let articlesArr = response.data;
  let searchTerm = articlesArr.shift();

  let titles = articlesArr[0];
  let summaries = articlesArr[1];
  let links = articlesArr[2];
  let articles = [];

  for (var i = 0; i < titles.length; i++) {
    articles.push({"title": titles[i], "summary": summaries[i], "link": links[i]});
  }

```

It looks like `map` is what I want, but I can’t figure out how to use map to convert an array of arrays into an object with specific keys.

Am I on the right track tinkering with `map`? Is this worth worrying about, or should I be satisfied that my app finds and displays results, and move on to making it look pretty?

---

<div class="post-metadata">

**Author:** ![PortableStick](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/portablestick/32/65591_2.png) [@PortableStick](https://forum.freecodecamp.org/u/PortableStick)\
**Post date:** [July 4, 2017, 5:20am UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/2 "2017-07-04T05:20:22Z")

</div>

> [@alightedlamp](#):
>
> Am I on the right track tinkering with map? Is this worth worrying about, or should I be satisfied that my app finds and displays results, and move on to making it look pretty?

You should always feel comfortable massaging data into whichever form makes it easier for you to work with. In this case, however, you can just get the data in the form you want by some deciphering Wikimedia’s arcane API. Here’s a link to the settings I use, which gets me an object much like what you’re making

> [@Wikipedia Viewer - Structure of Wikipedia API](https://forum.freecodecamp.org/t/wikipedia-viewer-structure-of-wikipedia-api/51830/2):
>
> You’re not alone. The Wikimedia API is incredibly confusing and in need of much better documentation. [Here](https://en.wikipedia.org/wiki/Special:ApiSandbox#action=query&format=json&list=search&srsearch=dog) are the parameters I use.

---

<div class="post-metadata">

**Author:** ![nhavar](https://avatars.discourse-cdn.com/v4/letter/n/c57346/32.png) [@nhavar](https://forum.freecodecamp.org/u/nhavar)\
**Post date:** [July 4, 2017, 6:02am UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/3 "2017-07-04T06:02:14Z")

</div>

I played around with map but couldn’t get to where you need with that. Here’s what I did instead… it still seems more complicated than it needs to be, but it’s early. Some refactoring on it later maybe. It would be far better if you have a means of getting a different format out of Wikipedia directly.

> **[GEdGeE](https://codepen.io/nhavar/pen/GEdGeE)**
>
> ...

---

<div class="post-metadata">

**Author:** ![ppc](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/ppc/32/63349_2.png) [@ppc](https://forum.freecodecamp.org/u/ppc)\
**Post date:** [July 4, 2017, 2:09pm UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/4 "2017-07-04T14:09:57Z")

</div>

Here’s a map-reduce soution:

```auto
let articles=articlesArr[0].map(
// map callback on titles array returns new article object per title
  (x, i) => ["title", "summary", "link"].reduce(
// reduce callback on property names inserts property into object
    (obj, prop, j) => {
// property value is from row corresponding to property index and
// column corresponding to title index
      obj[prop]=articlesArr[j][i]
      return obj
    },
    {}
  )
)

```

---

<div class="post-metadata">

**Author:** ![nhavar](https://avatars.discourse-cdn.com/v4/letter/n/c57346/32.png) [@nhavar](https://forum.freecodecamp.org/u/nhavar)\
**Post date:** [July 4, 2017, 3:45pm UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/5 "2017-07-04T15:45:14Z")

</div>

That’s far more compact and efficient than what I provided. Great example of two useful array functions together. Thank you @ppc.

---

<div class="post-metadata">

**Author:** ![ppc](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/ppc/32/63349_2.png) [@ppc](https://forum.freecodecamp.org/u/ppc)\
**Post date:** [July 4, 2017, 4:53pm UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/6 "2017-07-04T16:53:00Z")

</div>

If you like that you’re gonna love this - for details see [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration\_protocols](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols)

First override default array iterator to traverse two-dimensional array column by column

```javascript
// define columnwise iterator
articlesArr[Symbol.iterator]=()=>{
// track current column
  let col=0
  return {
    next: ()=>{
      let curcol=col++
// use titles array length for max columns
      return curcol < articlesArr[0].length?
        {
// new array size is same as source array
          value: Array.from(
            {length:articlesArr.length},
// fill new array with one value from each row of source array
            (x, i) => articlesArr[i][curcol]
          ),
          done: false
        }:
        {done:true}
    }
  }
}

```

Now generate objects from subarrays with `Array.from` that uses custom iterator

```javascript
// convert each array entry to an object
articles=Array.from(
// uses columnar iterator defined above
  articlesArr,
  x => ["title", "summary", "link"].reduce(
    (obj, prop, i) => {
// assign property corresponding value from array of column values
      obj[prop]=x[i]
      return obj
    },
    {}
  )
)

```

I actually prefer the original loop to these methods - it is simple and straightforward - these methods have merit and can be useful for other problems - it is easier to understand them in the context of a simple problem

---

<div class="post-metadata">

**Author:** ![alightedlamp](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/alightedlamp/32/63336_2.png) [@alightedlamp](https://forum.freecodecamp.org/u/alightedlamp)\
**Post date:** [July 4, 2017, 4:58pm UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/7 "2017-07-04T16:58:23Z")

</div>

Thanks @PortableStick! Lesson learned on digging through the documentation a bit more to see if I can get the data in the format I need.

And thanks @nhavar and @ppc – this is what I was looking for! While being able to get the data from their API in a more useable manner is much simpler, knowing how to solve these sorts of problems is useful as well and certainly a good learning experience, as it may not always be so simple. 🙂 Great stuff!

---

<div class="post-metadata">

**Author:** ![nhavar](https://avatars.discourse-cdn.com/v4/letter/n/c57346/32.png) [@nhavar](https://forum.freecodecamp.org/u/nhavar)\
**Post date:** [July 4, 2017, 11:48pm UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/9 "2017-07-04T23:48:17Z")

</div>

@SkyC I like that solution, it’s very simple and readable. Here’s a modification taking some of what @ppc did and yours and merging them together.

```auto
const results = [
  ["title1", "title2", "title3"],
  ["summary1", "summary2", "summary3"],
  ["link1", "link2", "link3"]
];

const articles = results[0].map((key, index) => {
  return {
    article: {
      title: results[0][index],
      summary: results[1][index],
      link: results[2][index]
    }
  };
});

```

---

<div class="post-metadata">

**Author:** ![camperextraordinaire](https://avatars.discourse-cdn.com/v4/letter/c/5f9b8f/32.png) [@camperextraordinaire](https://forum.freecodecamp.org/u/camperextraordinaire)\
**Post date:** [July 5, 2017, 7:26am UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/10 "2017-07-05T07:26:03Z")

</div>

If you don’t want to use a return statement with the arrow function, you can do:

```auto
const results = [
  ["title1", "title2", "title3"],
  ["summary1", "summary2", "summary3"],
  ["link1", "link2", "link3"]
];

const articles = results[0].map((_,idx) => 
  ({title: results[0][idx], summary: results[1][idx], link: results[2][idx]}));

```

---

<div class="post-metadata">

**Author:** ![alightedlamp](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/alightedlamp/32/63336_2.png) [@alightedlamp](https://forum.freecodecamp.org/u/alightedlamp)\
**Post date:** [July 6, 2017, 2:59am UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/11 "2017-07-06T02:59:55Z")

</div>

_That’s_ what I wanted. @SkyC, you’re right – that is much easier and locks in on the gap in my logic, but I was looking for a more readable solution. I wanted to be able to send the title, summaries, and links as props easily like `title={article.title}`, which looks nicer and is more legible than `title={article[0][i]}`, especially if those values will be used later in different contexts. Though, I guess the prop name itself _does_ make it clear what the value is. 😛

---

<div class="post-metadata">

**Author:** ![ILM](https://sea3.discourse-cdn.com/freecodecamp/user_avatar/forum.freecodecamp.org/ilm/32/363239_2.png) [@ILM](https://forum.freecodecamp.org/u/ILM)\
**Post date:** [January 17, 2021, 8:48pm UTC](https://forum.freecodecamp.org/t/working-vs-elegant-efficient/133896/12 "2021-01-17T20:48:47Z")

</div>

Closed on January 17, 2021, 8:48pm UTC


