olo
olo

Reputation: 5271

Convert nested array to an object

I am trying to use reduce to convert a nested array to an object.

I want to convert var bookprice = [["book1", "$5"], ["book2", "$2"], ["book3", "$7"]];

to

var bookpriceObj = {
    "book1": "$5", 
    "book2": "$2",
    "book3": "$7"
};

here is what I tried

var bookprice = [["book1", "$5"], ["book2", "$2"], ["book3", "$7"]];
bookpriceObj = {};
bookprice.reduce(function(a, cv, ci, arr){
    for (var i = 0; i < arr.length; ++i)
        bookpriceObj [i] = arr[i];

    return bookpriceObj ;
})

but the below result is not the desired result

{
    ["book1", "$5"]
    ["book2", "$2"]
    ["book3", "$7"]
}

Upvotes: 7

Views: 2123

Answers (7)

Joliver
Joliver

Reputation: 529

You are not returning the accumulated object in your reduce function and the for loop is not necessary.

Try:

const bookprice = [["book1", "$5"], ["book2", "$2"], ["book3", "$7"]];
const nameIndex = 0;
const priceIndex = 1;

const bookPricesObj = bookprice.reduce((prices, bookInfo) => {
    const name = bookInfo[nameIndex];
    const price = bookInfo[priceIndex];

    prices[name] = price;
    return prices;
}, {});

Upvotes: 1

zfrisch
zfrisch

Reputation: 8660

You can use reduce with Array Destructoring.

    bookpriceObj = bookprice.reduce((a, [b, c]) => (a[b] = c, a), {});

Here's what's happening:

  • a is the accumulator which has an initial value of the final parameter passed to reduce. The last value we pass is {} so it's an object
  • Array Destructoring can immediately assign values in an array to variables. a.e. [a, b] = ["one", "two"] assigns a with a value of "one" and b with a value of "two"
  • with each iteration over each item we assign the value of b(a.e. "book1") as a property on the object(a) and give it a value equal to c(a.e. "$2")
  • Each iteration of reduce you must return the accumulator(a)
  • When the whole thing is finally done, it'll store in bookpriceObj the result!

var bookprice = [ ["book1", "$5"], ["book2", "$2"], ["book3", "$7"]],
bookpriceObj = bookprice.reduce((a, [b, c]) => (a[b] = c, a), {});

console.log(bookpriceObj)

Upvotes: 4

A l w a y s S u n n y
A l w a y s S u n n y

Reputation: 38502

using Array.prototype.reduce to convert a nested array to an object

var bookprice = [
  ["book1", "$5"],
  ["book2", "$2"],
  ["book3", "$7"]
];
bookpriceObj = bookprice.reduce(function(acc, cur, i) {
  acc[cur[0]] = cur[1];
  return acc;
}, {})

console.log(bookpriceObj);

Upvotes: 0

mpm
mpm

Reputation: 20155

You need to return an object from the "reducer" AKA the first argument of reduce, and use an empty object as second argument.

var bookprice = [
  ["book1", "$5"],
  ["book2", "$2"],
  ["book3", "$7"]
];

var result = bookprice.reduce(function(object, el) {
  object[el[0]] = el[1]
  return object;
}, {})

console.log(result)

You don't need a for loop since reduce already iterates over the array.

Upvotes: 4

Orelsanpls
Orelsanpls

Reputation: 23505

Using Array.reduce(), Array destructuration, Dynamical keys and Spread operator.

const bookprice = [
  ['book1', '$5'],
  ['book2', '$2'],
  ['book3', '$7'],
];

const ret = bookprice.reduce((tmp, [
  name,
  price,
]) => ({
  ...tmp,

  [name]: price,
}), {});

console.log(ret);

Upvotes: 1

Alex Dovzhanyn
Alex Dovzhanyn

Reputation: 1046

bookprice.reduce((acc, price) => {
  let tmp = {}
  tmp[price[0]] = price[1]
  return Object.assign(acc, tmp)
}, {})

Upvotes: 1

Emeeus
Emeeus

Reputation: 5250

Using forEach is shorter

var bookprice = [["book1", "$5"], ["book2", "$2"], ["book3", "$7"]];

var bookpriceObj = {};


bookprice.forEach(e=>bookpriceObj[e[0]] = e[1]);

console.log(bookpriceObj)

Upvotes: 12

Related Questions