John Q
John Q

Reputation: 13

Make 'value' of [key, value] Pair into Array

I have a simple object I want to turn into key value pairs to display in a SectionList.

const DOBBY = {
  foo: 'bar',
  toto: ['hoge', 'piyo'],
};

I used Objects.entries() to turn it into an array of objects:

const toArray = Object.entries(DOBBY).map(([ title, data ]) => ({ title, data }));

So that I get back:

[
  { title: 'foo', data: 'bar' },
  { title: 'toto', data: ['hoge', 'piyo'] },
];

Right now SectionList splits 'bar' into three rows.
How do I put 'bar' into an array so that I get:

[
 { title: 'foo', data: ['bar'] },
 { title: 'toto', data: ['hoge', 'piyo'] },
]

I think Array.of() will do it, but I don't know where to implement it, or whether there's something I can do with .map()

Upvotes: 1

Views: 80

Answers (2)

Terry
Terry

Reputation: 66103

You can simply force nest data into a sub-array, and then flatten it using Array.prototype.flat:

  • When data is an array, [data] will be an array with a single element that is also an array, so Array.flat will flatten it into an array
  • When data is a string, [data] will be an array of string, and Array.flat will preserve the way it is

const DOBBY = {
  foo: 'bar',
  toto: ['hoge', 'piyo'],
};

const toArray = Object.entries(DOBBY).map(([ title, data ]) => ({ title, data: [data].flat() }));
console.log(toArray);

Of course, you can also go for a slightly long winded way, but that means you don't unneedingly nest array within an array:

const DOBBY = {
  foo: 'bar',
  toto: ['hoge', 'piyo'],
};

const toArray = Object.entries(DOBBY).map(([ title, data ]) => {
  return {
    title,
    data: Array.isArray(data) ? data : [data]
  };
});
console.log(toArray);

The Array.prototype.flat() method is of course slower, because you will be performing additional array nesting. That's a sacrifice you pay for readability. Also, for very small objects and arrays, this performance overhead is probably negligible:

https://jsperf.com/array-prototype-flat-vs-isarray/

+---------------------------------+------------+------------+------------+
|               Test              | Chrome 80  | Firefox 74 | Safari 13  |
+---------------------------------+------------+------------+------------+
| Array.prototype.flat() approach | 640k ops/s | 2.4m ops/s | 590k ops/s |
| Array.isArray approach          | 2.6m ops/s | 2.7m ops/s | 650k ops/s |
+---------------------------------+------------+------------+------------+

Upvotes: 2

mgreif
mgreif

Reputation: 131

Just check if it is an Array, if so just insert the data, if not put the data into an empty Array

const DOBBY = {
  foo: 'bar',
  toto: ['hoge', 'piyo'],
};

const toArray = Object.entries(DOBBY)
.map(([title, data ]) => ({ title, data: Array.isArray(data) ? data : [data] }));

it worked for me, so i hope this helps :)

Upvotes: 0

Related Questions