2

I'm working to understand Array.reduce() in JavaScript. I have an array of objects that I'm trying to apply .reduce() to, but I'm getting back an array of single letter strings.

Goal:

["Stuff", "necklace", "ring", "bracelet"]

Current Array of Objects

const productArray =
[
    {
        id: 1,
        productTitle: "Necklace"
    },
    {
        id: 2,
        productTitle: "Ring"
    },
    {
        id: 3,
        productTitle: "Bracelet"
    }
]

Function call

const newStuff = productArray.reduce(function(a, currentValue) {
    return [...a, ...currentValue.productTitle];
}, ["Stuff"])

Actual result: weirdArray

What do I need to do to specify that I don't want "productTitle" broken down into single-letter strings? I have been looking for resources regarding .reduce() on an array of objects but I haven't found anything very helpful. Any pointers?

1
  • Don't post images, post your code as a runnable snippet. Commented Apr 3, 2018 at 20:47

5 Answers 5

5

To concatenate an array and value when using spread to create a new array, you spread the previous array to the new array, and add the new item without spreading it.

const productArray = [{"id":1,"productTitle":"Necklace"},{"id":2,"productTitle":"Ring"},{"id":3,"productTitle":"Bracelet"}];

const newStuff = productArray.reduce((a, currentValue) => 
  [...a, currentValue.productTitle], []);

console.log(newStuff);

In this case, it's better to use Array.map():

const productArray = [{"id":1,"productTitle":"Necklace"},{"id":2,"productTitle":"Ring"},{"id":3,"productTitle":"Bracelet"}];

const newStuff = productArray.map((currentValue) => currentValue.productTitle);

console.log(newStuff);

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

Comments

0

Do not spread the title, pass it as it is:

const newStuff = productArray.reduce(function(a, currentValue) {
  return [...a, currentValue.productTitle];
}, ["Stuff"]);

...currentValue.productTitle spreads into an array of individual letters, you only want to spread a variable, the aggregate here.

Comments

0

Basically a string is iterable, because the iterator is implemented and returns an array of single characters, if using spread syntax ....

Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.

console.log([...'foo']);

Comments

0

Other answers have pointed out why your code is wrong. But I do want to also note that what you're doing is already covered by Array.prototype.concat:

const productArray = [{"id":1,"productTitle":"Necklace"},{"id":2,"productTitle":"Ring"},{"id":3,"productTitle":"Bracelet"}];

const newStuff = productArray.reduce((a, val) => a.concat(val.productTitle), ['Struff']);
console.log(newStuff);

(And of course, as another answer has mentioned, this sounds more like a use for map than reduce, which might not matter since you're using this to learn reduce.)

Comments

0

The use of spread in this case is unnecessary and inefficient as it creates a new accumulator array from the previous one on every iteration. You can remove spread (and fix your issue) and use concat instead to keep it as a one-liner.

However, since you're just adding one new value on each iteration, you should use push. It requires one more line of code but is likely more efficient than using concat.

var productArray = [{id: 1,productTitle: "Necklace"},
                    {id: 2,productTitle: "Ring"},
                    {id: 3,productTitle: "Bracelet"}
];

// Using concat
var newStuff = productArray.reduce((acc, value) =>
  acc.concat(value.productTitle),
["Stuff"]);

console.log(newStuff);

// Using push
var newStuff = productArray.reduce((acc, value) => {
  acc.push(value.productTitle);
  return acc;
}, ["Stuff"]);

console.log(newStuff);

1 Comment

The text suggests push, but the code is using concat.

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.