web-dev-qa-db-ja.com

reduceを使用して配列をオブジェクトの配列に変換します

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

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

optimizedRouteを結果に変換したい。 ES6 .reduce()でこれを行いたいです。ここに私が試したものがあります:

_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)
_
24
kartik

reduceを使用して、ルートの開始部分と終了部分を取得し、次の開始のために終了を返すことができます。

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

@ EDITGrégoryNEUT説明の追加

// 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;
}
14
Nina Scholz

ループを使用する対応するコードはすぐに読み取り可能であり、説明を必要としないため、「with reduce」要件を実際には理解していません。

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)

時々賢いことをするのは楽しいですが、答えのいくつかはこれに比べて非常に複雑です!

11
Tom Fenech

別のアプローチは、mapと組み合わせてsliceメソッドを使用することです。 map関数の場合、callback関数をargumentとして渡す必要があります。これは、指定された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);
11

reduceの例を次に示します。これがこれを行う最も自然な方法であるかどうかはわかりません!

reduceを使用するのは非常にやり過ぎだと感じます。そのような場合(ただし、それは私の意見です)、自然にインデックスを使用するので、まあ、単純な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);
4
sjahan

reduceを要求したので、これを行う1つの方法を次に示します。

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

reduceは、配列を単一の値に減らすことを試みていないため、実際にはここに収まりません。

完璧な世界では、通常はmapとして知られている multi-array Zip version になります。

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

ただし、JavaScriptにはありません。最良の代替方法は、 Array.from を使用して、ルートへのインデックスの範囲でmapを使用することです。

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

Nina scholzの答えを簡略化しました。ninaのアイデアでは、reduceを使用してルートの開始部分と終了部分を取得し、次の開始のために終了を返します。

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

次のコードは、Spread operatorTernary operator、および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);
2
Grégory NEUT

読みやすさを好みますちょうどを解決する短いコード

_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;
}, []);
_

また、そのソリューションは短くなりましたが、読みやすさを犠牲にしました(少なくとも私にとって):

_optimizedRoute.reduce((routes, city) => {
  routes.last().start = city;
  routes.Push({ end: city });
  return routes;
}, [{}]).slice(1, -1);
_

last()については、読みやすさのために通常使用する関数です。

_Array.prototype.last = function() { 
  return this[this.length - 1] 
}
_
0
Francute