1

I want to turn the following object

const order = {
  apple: 5,
  banana: 5,
  orange: 5
};

into the following object, with each key being assigned its index in the object as its value

{
  apple: 0,
  banana: 1,
  orange: 2
}

This is the code I have but it's not working and I don't know why.

const indices = Object.keys(order).reduce(
    (previousValue, currentValue, currentIndex) =>
      (previousValue[currentValue] = currentIndex), {}
  );
TypeError: Cannot create property 'banana' on number '0'

What am I doing wrong here?

3
  • 3
    Arrays have indexes. I'm not sure it's sensible to try and infer an ordering for attributes in an object (or dict/hashtable-like data structure), even if you can technically do it in some languages. Why do you want the 'index'? Commented Feb 24, 2022 at 0:26
  • 1
    There is no specification in JS that requires plain objects {} to have any ordering to keys - so things like Object.keys are not really deterministic (eg. you might not get the same thing back on on multiple calls). However, I have found in practice that the keys are generally returned in the order they were added. I would not stake any critical business functionality on this though as it could change any day without notice. Commented Feb 24, 2022 at 0:52
  • @RyanWheale This is just for a university project I'm building so I won't be worrying about things like that. Regardless, thank you for that insightful comment :) Commented Feb 24, 2022 at 0:59

2 Answers 2

2

Reducer is expected to return the accumulator:

const order = {
  apple: 5,
  banana: 5,
  orange: 5
};

const indices = Object.keys(order).reduce(
  (previousValue, currentValue, currentIndex) => {
    previousValue[currentValue] = currentIndex;
    return previousValue; // <-- this was missing in your attempt.
  }, {}
);

console.log(indices);

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

1 Comment

It would have been more precise to write "accumulated result". While here it is the same object, it could be something new, like if someone writes an own join() with reduce(), [1,2,3].reduce((acc,item)=>acc+","+item), in every iteration a brand new string has to be created simply because strings are immutable.
1
const order = {
    apple: 5,
    banana: 5,
    orange: 5,
};

const mapByIndex = (obj) => {
    return Object.keys(obj).reduce((acc, curr, i) => {  
        return {
            ...acc,
            [curr]: i,
        };
    }, {});
};

console.log(mapByIndex(order)); // -> { apple: 0, banana: 1, orange: 2 }

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.