Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array to Object es6 javascript

I am trying to see if there is a smaller way of converting an array to an object in es6. ( I do not have to worry about cross-browser )

I currently have:

function (values) // values being an array.
{   
    let [videos, video_count, page] = values;
    let data = { videos, video_count, page };
    someFunctions(data);
    moreFunctions(data);
}

But I was wondering if it's possible to cut out the first line of the function, let [videos....] part. And somehow inline do the conversion.

I have read through mozilla: Destructuring assignment but I could not see it there. (but I may have understood it wrong) and I am really not clever enough to understand ECMA: ES6 Spec.

I suspect it is not possible and the above is already the simplest I can make it. But if I can get away with not creating the videos, video_count & page tmp variables I would be happier.

like image 570
WORMSS Avatar asked Sep 24 '26 19:09

WORMSS


2 Answers

You can destructure right in the function parameters

function myFunc([ videos, video_count, page ])
{   
    let data = { videos, video_count, page };
    someFunctions(data);
    moreFunctions(data);
}

myFunc(values);

I do a lot of data abstraction using this technique

// basic abstraction
const ratio = (n, d) => ({n, d});
const numer = ({n}) => n;
const denom = ({d}) => d;

// compound abstraction using selectors
const ratioAdd = (x,y) => ratio(
  numer(x) * denom(y) + numer(y) * denom(x),
  denom(x) * denom(y)
);

// or skip selectors if you're feeling lazy
const printRatio = ({n,d}) => `${n}/${d}`;

console.log(printRatio(ratioAdd(ratio(1,3), ratio(1,4)))); //= 7/12

You seem hell-bent on somehow making the code shorter, so here you go. In this case, "making it shorter" means making it longer first.

// Goal:
obuild(keys,values) //=> ourObject

Generic procedures zip, assign, and obuild should give us what we need. This is vastly superior to @CodingIntigue's answer as it's not one big function that tries to do all of the tasks. Keeping them separate means reducing complexity, and increasing readability and reusability.

// zip :: [a] -> [b] -> [[a,b]]
const zip = ([x,...xs], [y,...ys]) => {
  if (x === undefined || y === undefined)
    return [];
  else
    return [[x,y], ...zip(xs,ys)];
}

// assign :: (Object{k:v}, [k,v]) -> Object{k:v}
const assign = (o, [k,v]) => Object.assign(o, {[k]: v});

// obuild :: ([k], [v]) -> Object{k:v}
const obuild = (keys, values) => zip(keys, values).reduce(assign, {});

let keys = ['a', 'b', 'c'];
let values = [1, 2, 3];

console.log(obuild(keys,values));
// { 'a': 1, 'b': 2, 'c': 3 }
like image 195
Mulan Avatar answered Sep 27 '26 09:09

Mulan


With the given properties and names you have, that's probably the shortest way to achieve your desired result.

However, if you had more fields, you could use reduce to avoid repetition. It's not as readable as the destructuring though:

let data = values.reduce((prev, val, index) => Object.assign(prev, {[["videos", "video_count", "page"][index]]: val} ), {});

You could then abstract that out into a generic function:

const values = ["test1","test2","test3"];
const mapArrayToObject = (array, fields) =>
  array.reduce(
    (prev, val, index) => Object.assign(prev, { [fields[index]]: val } ),
    {}
  );
const data = mapArrayToObject(values, ["videos", "video_count", "page"]);
console.log(data);
like image 23
CodingIntrigue Avatar answered Sep 27 '26 10:09

CodingIntrigue



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!