Transform an array into an array of objects using the reduce method

optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore']

result = [
  {start: bengaluru, end: salem},
  {start: salem, end: erode},
  {start: erode, end: tiruppur},
  {start: tiruppur, end: coimbatore},
]

I am looking to transform the optimizedRoute array into the desired result using ES6's .reduce() method. Below is an attempt I made:

const r = optimizedRoute.reduce((places, place, i) => {
  const result: any = [];
  places = []
  places.push({
    startPlace: place,
    endPlace: place
  });
  // result.push ({ startplace, endplace, seats: 4 });
  // console.log(result);
  return places;
}, {});
console.log(r)

Answer №1

One way to extract the start and end parts of a route is by using the reduce method, where the end becomes the start for the next iteration.

getParts = a => (
    r => (
        a.reduce((start, end) => (
            r.push({ start, end }),
            end
        )),
        r
    )
)([]);

const getParts = a => (r => (a.reduce((start, end) => (r.push({ start, end }), end)), r))([]);

var optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore']

console.log(getParts(optimizedRoute));
.as-console-wrapper { max-height: 100% !important; top: 0; }


@EDIT Grégory NEUT adding explanation

// Two things to be aware of first:
// When no initial value is provided,
// Array.reduce takes the index 0 as the first value and starts looping from index 1

// Doing (x, y, z)
// Will execute the code x, y, and z

// Equivalent to:

// x;
// y;
// z;

let ex = 0;

console.log((ex = 2, ex = 5, ex = 3));

// Breaking down the code

const getParts = (a) => {
  const func = (r) => {
    a.reduce((start, end) => {
      console.log(start, end);

      r.push({
        start,
        end,
      });

      return end;
    });
    return r;
  };

  return func([]);
};

// Equivalent version
const getPartsEquivalent = (a) => {
  const r = [];
  
  a.reduce((start, end) => {
    console.log(start, end);
    
    r.push({
      start,
      end,
    });
    
    return end;
  });
  
  return r;
};

var optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore'];

console.log(getPartsEquivalent(optimizedRoute));
.as-console-wrapper {
  max-height: 100% !important;
  top: 0;
}

Answer №2

If you're looking for a different technique, consider utilizing the map method along with slice. When using the map function, be sure to specify a callback function as an argument that will be executed on each item in your specified array.

optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore']
var result = optimizedRoute
                .slice(0, -1)
                .map((item, index) => ({start : item, end : optimizedRoute[index + 1]}));
console.log(result);

Answer №3

I find the requirement of using "reduce" a bit confusing, as the code with a simple loop is clear and self-explanatory:

const optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore'];
const result = new Array(optimizedRoute.length - 1);

for (let i = 0; i < result.length; ++i) {
  result[i] = {
    start: optimizedRoute[i],
    end: optimizedRoute[i + 1]
  };
}

console.log(result)

While it's fun to come up with clever solutions, sometimes simplicity is best compared to overly complex answers!

Answer №4

Let's explore an example using the reduce method. However, some might argue that this approach may not be the most intuitive.

While some might find using reduce to be a bit excessive in scenarios where using an index seems more appropriate, I personally prefer a straightforward for loop.

const optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore'];
let startCity;
const result = optimizedRoute.reduce((acc, city) => {
  if(startCity) {
    acc.push({start: startCity, end: city});
  }
  startCity = city;

  return acc;
}, []);

console.log(result);

Answer №5

Here is a solution using the reduce function:

let cities = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore']
   
let routes = cities.reduce((accum, city, index)=>{
   if(index == cities.length - 1) 
      return accum;
   accum.push({start: city, end: cities[index+1]})
   return accum;
}, [])

console.log(routes);

Answer №6

reduce isn't quite the right choice here since the goal isn't to condense the array into a single value.

In an ideal scenario, we would have a multi-array map option, commonly referred to as zip, that could be implemented like this:

const result = zipWith(optimisedRoute.slice(0, -1),
                       optimisedRoute.slice(1),
                       (start, end) => ({start, end}));

Unfortunately, such a feature doesn't exist in JavaScript. The next best approach is to use map on a range of indices within the route using Array.from:

const result = Array.from({length: optimisedRoute.length - 1}, (_, index) => {
     const start = optimisedRoute[index];
     const end = optimisedRoute[index + 1];
     return {start, end};
});

Answer №7

The code snippet below demonstrates the utilization of the Spread operator, Ternary operator, and Array.reduce.

const optimizedRoute = [
  'Bengaluru',
  'Salem',
  'Erode',
  'Tiruppur',
  'Coimbatore',
];

// Determining if we are at the last value in the array or not
// If it is the last value, return the constructed array
// If not, add a new value to the existing array.

// tmp represents the array being constructed
// x refers to the current loop item
// xi indicates the index of the current item
const lastItemIndex = optimizedRoute.length - 1;

const result = optimizedRoute.reduce((tmp, x, xi) => xi !== lastItemIndex ? [
  ...tmp,

  {
    start: x,
 
    // Accessing the next item by using the position of
    // the current item (xi)
    end: optimizedRoute[xi + 1],
  },
] : tmp, []);

console.log(result);

Answer №8

In my simplified version of Nina Scholz's solution, I have implemented her idea of using reduce to extract the start and end parts of a route, returning the end as the next start.

getRouteParts = routes => {
  const result = [];
    routes.reduce((start, end) => {
      result.push({ start, end });
      return end;
    });
    return result;
};
var optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore'];
console.log(this.getRouteParts(optimizedRoute));

Answer №9

Prioritizing readability is more important to me than opting for concise code that simply gets the job done

When working with optimizedRoute, I like to use this function to enhance clarity and organization:

Also, while a shorter solution may save space, it can sacrifice readability in my opinion. Consider this alternative approach:

With optimizedRoute, I find it helpful to utilize the following method for improved understanding:

Answer №10

Here is a solution using the ReduceRight method.

optimizedRoute.reduceRight((acc, d, i, arr) => 
             i == 0 
                ? acc 
                : [{ start: arr[i -1], end: d }, ...acc]  
            , [])

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I apply JavaScript to aggregate child node values and assign them to the parent in JSON data format?

I receive a dynamic JSON from the server, which has varying structures. Each data entry consists of a chapter with stages and/or review sets at the root level. If a stage exists, there will be either a review set array or another stage. The review set cont ...

I possess 9 captivating visuals that gracefully unveil their larger counterparts upon being clicked. Curiously, this enchanting feature seems to encounter a perplexing issue within the realm of web browsing

<style type="text/javascript" src="jquery-1.11.0.min.js"></style> <style type="text/javascript" src="myCode.js"></style> </body> //jquery is within my site directory on my desktop $(document).ready(function(){ //note: $("#ar ...

Unexpected Error: Unable to access the 'position' property of an undefined element (D3.JS)

This error occurred when I attempted to fetch JSON data and convert it into a line graph. An unexpected TypeError was thrown: Unable to access the 'position' property of undefined Below is the relevant portion of the JS code: d3.json("../js/ ...

What steps do I need to take to execute a browserify-ed application in NodeJS?

I have an interesting challenge on my hands - I need to modify a sizable JavaScript codebase to be compatible with NodeJS. The current code follows the CommonJS style and utilizes a gulp build process involving browserify and deamdify. While I am somewhat ...

Retrieve information from the JSON output

Currently, I am working on an Android project and dealing with a JSON string. Below is how the JSON string appears: {"objectA":{"objectB","objectC","objectD":[{"Element1":"value1","Element2":"value2"}]}} My objective is to extract objectD as a JSONArray. ...

Issues encountered when trying to execute npm start: "The function this.htmlWebpackPlugin.getHooks is not recognized."

My background in web development is weak, and I'm facing a challenging situation. I had to take over the work of a colleague who left, and now I'm trying to finish the site we were working on. Since then, I've been learning about web develop ...

Showing JSON information in an Angular application

Upon page load, I am encountering an issue with retrieving and storing JSON data objects in Angular scope for use on my page and in my controller. When attempting to access the value, I receive the error message: angular.js:11655 ReferenceError: data is ...

Clicked button redirects user to the parent URL

When the application is running on page http://localhost:3000/login, clicking a button should redirect to http://localhost:3000/. This is how I attempted it: import React from 'react'; import { Redirect } from 'react-router-dom'; impor ...

Creating methods in Vue that can alter elements created during the mounted lifecycle hook can be achieved by defining functions

I am trying to implement a button that can recenter the canvas. The idea is that when the button is clicked, it will trigger the rec() method which should reposition the canvas that was created in the mounted() function. However, this setup is not working ...

Will a notification box appear upon submission indicating success or failure?

After the submit button is clicked, I need a pop-up box to display either a successful or failed message. Then confirm the message by clicking OK. Currently, I am seeing an "undefined" pop-up followed by a failed message pop-up. Can someone please assist m ...

What is the method to adjust the anchor point for a MUI popover?

I currently have the following code for handling a popover: const [open, setOpen] = useState(false); const anchorRef = createRef() const handleClose = () => { setOpen(false); }; const handleClick = useCallback( (event: MouseEvent<H ...

Exploring the Power of 2D Arrays in JavaScript

Hey there! I'm having trouble defining a 2D array in JS. Two errors are getting in my way and I can't figure out what's going wrong. i is generated by a for loop - it's defined. Even when I try replacing i with 0, the same error occurs. ...

Display a loading GIF for every HTTP request made in Angular 4

I am a beginner with Angular and I am looking for a way to display a spinner every time an HTTP request is made. My application consists of multiple components: <component-one></component-one> <component-two></component-two> <c ...

XMLHttpRequest request shows blank result

Issue: After clicking the submit button on my HTML form, a JavaScript function is called with an Ajax request. The request returns successfully, but the result disappears quickly. I'm curious if I may be overlooking something here (besides jQuery, w ...

Searching for the name of dynamically generated input fields using jQuery

I have a straightforward form featuring radio buttons <form> <input type="radio" name="radio_1" value="1" />Radio 1 <input type="radio" name="radio_1" value="2" />Radio 2 <input type="radio" name="radio_1" value="3" />Radio 3 </ ...

"Why is it that the keypress event doesn't function properly when using the on() method

My goal is to capture the enter event for an input field $("input[name='search']").on("keypress", function(e){ if (e.which == '13') { alert('code'); } }); This is the HTML code snippet: <input name="searc ...

Is it possible for Angular to perform bidirectional data binding in reverse between two input fields?

I'm struggling to get my two input fields to update values when the opposite input is changed. My goal is to create a simple $dollar to Gold oz calculator with two input fields. You can see a sample preview here: http://embed.plnkr.co/dw6xL95zRqJC1p ...

Implementing group validation with Angular

What is the proper validation method for a form group control with code length containing decimal fields? Currently, my code is as follows: this.control = new FormControl(val, [Validators.required, Validators.maxLength(items.CodeLength)]); However, I am ...

Leveraging the power of AngularJS to run JavaScript functions saved as strings

Is it possible to dynamically inject JavaScript code that is stored in a string into AngularJS controllers? var dynamicJS = "function DoSomething(value){var x = 1+1 return 2;}" I need to inject the above function dynamically into my AngularJS controller ...

What could be causing the malfunction of my token rotation feature in nextAuth?

I am developing a web application that involves working with an external API alongside my team member. We are making API requests using Next.js. I have implemented nextAuth for authentication, but I am facing issues with token rotation. After successful lo ...