7

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"]
}
1
  • 2
    Seems to me like you're trying to use a reducer like it's a for loop, but it's a different concept. Do not reference variables that are outside it, all the things are already in the arguments of the reducer. The same accumulator is passed through the whole thing element by element, and you "collect" things to it (or sum or what have you). But in this case a simple for loop would probably be way faster. Commented Aug 24, 2018 at 15:46

7 Answers 7

12

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)

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

2 Comments

You have an entry value, a loop over an array and an end value, it's definitely a fit for Array.reduce
@GrégoryNEUT I know, but I'm not a big fan of reduce for this situations, the end value is an object, not a single value (which is the purpose). I think is more clear using loops. In my opinion, reduce() is better to reduce, to find one single value as end value.
4

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.

Comments

4

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)

Comments

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

1 Comment

Please add some explanation to your answer.
1

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

Comments

1

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

Comments

0

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

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.