optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore']
result = [
{start: bengaluru, end: salem},
{start: salem, end: erode},
{start: erode, end: tiruppur},
{start: tiruppur, end: coimbatore},
]
Je veux convertir optimizedRoute
en résultat. Je veux faire ceci avec ES6 .reduce()
. Voici ce que j'ai essayé:
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)
Vous pouvez utiliser reduce
pour obtenir le début et la fin d'une partie de l'itinéraire et renvoyer la fin pour le prochain début.
getParts = a => ( // take a as array and return an IIFE
r => ( // with an initialized result array
a.reduce((start, end) => ( // reduce array by taking two values
r.Push({ start, end }), // Push short hand properties
end // and take the last value as start value for next loop
)),
r // finally return result
)
)([]); // call IIFE with empty array
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 ajout d'explication
// Two thing to know first :
// When no initial value is provided,
// Array.reduce takes the index 0 as first value and start to loop at 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));
// So about the code
const getParts = (a) => {
// We are creating a new function here so we can have an array where to
// Push data to
const func = (r) => {
// Because there is no initial value
//
// Start will be the value at index 0 of the array
// The loop is gonna start at index 1 of the array
a.reduce((start, end) => {
console.log(start, end);
r.Push({
start,
end,
});
return end;
});
return r;
};
return func([]);
};
// Equivalent
const getPartsEquivalent = (a) => {
const r = [];
// Because there is no initial value
//
// Start will be the value at index 0 of the array
// The loop is gonna start at index 1 of the array
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;
}
Je ne comprends pas vraiment l'exigence "avec réduction", car le code correspondant utilisant une boucle est immédiatement lisible et ne nécessite aucune explication:
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)
C'est amusant de faire des choses intelligentes parfois, mais certaines des réponses sont très compliquées comparées à cela!
Une autre approche consiste à utiliser la méthode map
en combinaison avec slice
. Pour la fonction map
, vous devez passer une fonction callback
en tant que argument qui sera appliqué à chaque élément de votre tableau .
optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore']
var result = optimizedRoute
.slice(0, -1)
.map((item, index) => ({start : item, end : optimizedRoute[index + 1]}));
console.log(result);
Voici un exemple avec reduce
. Je ne suis pas sûr que ce soit la façon la plus naturelle de le faire!
Utiliser reduce
me semble excessif et dans ce genre de cas (mais ce n'est que mon opinion), où j'utiliserais naturellement un index, eh bien, je choisirais une simple boucle for
.
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);
Puisque vous avez demandé reduce
, voici une façon de le faire:
let optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore']
let res = optimizedRoute.reduce((accum, item, i)=>{
if(i == optimizedRoute.length - 1)
return accum;
accum.Push({start: item, end: optimizedRoute[i+1]})
return accum;
}, [])
console.log(res);
reduce
ne correspond pas vraiment à la facture ici car vous n'essayez pas de réduire le tableau à une valeur unique.
Dans un monde parfait, nous aurions multi-tableau map
version , généralement appelée Zip
, que nous pourrions utiliser comme
const result = zipWith(optimisedRoute.slice(0, -1),
optimisedRoute.slice(1),
(start, end) => ({start, end}));
mais il n'y en a pas en JavaScript. La meilleure alternative est de map
sur une plage d'index dans la route à l'aide de Array.from
:
const result = Array.from({length: optimisedRoute.length - 1}, (_, index) => {
const start = optimisedRoute[index];
const end = optimisedRoute[index + 1];
return {start, end};
});
J'ai simplifié la réponse de nina scholz, Selon l’idée de nina, utilisez réduire pour obtenir le début et la fin d’une partie de l’itinéraire et renvoyer la fin pour le prochain début.
getParts = a => {
const result = [];
a.reduce((start, end) => {
result.Push({ start, end });
return end;
});
return result;
};
var optimizedRoute = ['Bengaluru', 'Salem', 'Erode', 'Tiruppur', 'Coimbatore'];
console.log(this.getParts(optimizedRoute));
Le code suivant utilise Spread operator
, Ternary operator
et Array.reduce
.
const optimizedRoute = [
'Bengaluru',
'Salem',
'Erode',
'Tiruppur',
'Coimbatore',
];
// Look if we are at dealing with the last value or not
// If we do only return the constructed array
// If we don't, add a new value into the constructed array.
// tmp is the array we are constructing
// x the actual loop item
// xi the index of the item
const lastItemIndex = optimizedRoute.length - 1;
const ret = optimizedRoute.reduce((tmp, x, xi) => xi !== lastItemIndex ? [
...tmp,
{
start: x,
// We access to the next item using the position of
// the current item (xi)
end: optimizedRoute[xi + 1],
},
] : tmp, []);
console.log(ret);
Je préfère la lisibilité plutôt que le code court qui le résout
optimizedRoute.reduce((routes, city, index) => {
const firstCity = index === 0;
const lastCity = index === optimizedRoute.length - 1;
if (!firstCity) {
routes.last().end = city;
}
if (!lastCity) {
routes.Push({ start: city });
}
return routes;
}, []);
En outre, cette solution simplifiée mais qui rend la lecture moins lisible (du moins pour moi) pourrait être:
optimizedRoute.reduce((routes, city) => {
routes.last().start = city;
routes.Push({ end: city });
return routes;
}, [{}]).slice(1, -1);
Et à propos de last()
, c’est une fonction que j’utilise normalement pour la lisibilité:
Array.prototype.last = function() {
return this[this.length - 1]
}