Ramda.jsを使用してJavascriptの2D配列に動的に挿入する方法

MattisW

私は次の状態にあります

{
  "array": [
    [
      "Name",
      "Phone",
      "Email"
    ]
  ],
  "indexes": {
    "Name": 0,
    "Phone": 1,
    "Email": 2
  },
  "tempInput": ["[email protected]","[email protected]"],
  "tempDestination": "Email"
}

ここで、オブジェクトを取得し、入力値を新しい行として指定された宛先の2D配列に動的に挿入し、最終的に

{
  "array": [
    [
      "Name",
      "Phone",
      "Email"
    ],
    [
      "",
      "",
      "[email protected]"
    ],
    [ 
      "",
      "",
      "[email protected]"
    ]
  ],
  "indexes": {
    "Name": 0,
    "Phone": 1,
    "Email": 2
  }
}

これを解決するために、私はドキュメントを見て、発見しました

R.lensPropおよびR.view。この組み合わせは私に出発点を提供します(つまり、提供された目的地の正しいインデックスを取得しますが、それ以降は行き詰まります。

const addInputToArray = ({ array, indexes, tempDestination, tempInput, }) => {
  // Use Lense and R.view to get the correct index
  const xLens = R.lensProp(tempDestination);
  R.view(xLens, indexes), // contains index

  // Insert the 2 Rows into newArray - I'm lost on this part.
  const newArray = array.push( // newRows )

  return {
    array: newArray,
    indexes: indexes
  }
}

たとえばmap関数を使用して、入力をループする必要があることはわかっています。しかし、正しい配列結果を得るためにmap関数が何を実行すべきかについて私は迷っています。

ここで私を助けてくれたら素晴らしいと思いますか?

スコット・サウエ

更新

コメントは追加の要件(私が期待したもの)を求めています。それはわずかに異なるアプローチを必要とします。これが私の見解です:

const addInputToArray = (
  { array, indexes, tempDestination, tempInput, ...rest},
  index = indexes[tempDestination]
) => ({
  array: tempInput .reduce (
    (a, v, i) =>
      (i + 1) in a
        ? update ( (i + 1), update (index, v, a [i + 1] ), a)
        : concat (a, [update (index, v, map (always(''), array[0]) )] ),
    array
  ),
  indexes,
  ...rest
})

const state = {array: [["Name", "Phone", "Email"]], indexes: {Name: 0,
Phone: 1, Email: 2}, tempInput: ["[email protected]","[email protected]"],
tempDestination: "Email"}

const state2 = addInputToArray (state)

console .log (
  state2
)

const state3 = addInputToArray({
  ...state2,
  tempInput: ['Wilma', 'Fred', 'Betty'],
  tempDestination: 'Name'
})

console .log (
  state3
)

const state4 = addInputToArray({
  ...state3,
  tempInput: [123, , 456],
  //              ^------------- Note the gap here
  tempDestination: 'Phone'
})

console .log (
  state4
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script> const {update, concat, map, always} = R;                    </script>

元のバージョン(下記)では、Ramda関数は必要ないことに注意してください。ここでは、updateそれはきれいになり、そして私はRAMDAを使用している場合、私はまた、使用するので、それは、物事を単純化しどこに、私は同様にそれを使用するかもしれないconcatの代わりにArray.prototype.concat、使用する代わりのようなものでこれらにより、コードがいくらか読みやすくなることがわかりました。map (always(''), array[0])Array (array [0] .length) .fill ('')

これらの最後のものは非常に簡単に削除できますが、ライブラリなしでこれを作成updateする場合は、これをインライン化した場合よりもコードをクリーンにする呼び出しとして、に似たものを作成することをお勧めします

代替API

ここではかなりオフベースになる可能性がありますが、ここで記述しようとしているAPIは、基本的な要件が示すよりもさらに複雑であると思われます。そのインデックスのリストは、コードの臭い、解決策以上の回避策として私を襲います。(実際、配列の最初の行から簡単に導き出すことができます。)

たとえば、私は次のようなAPIを好むかもしれません:

const addInputToArray = ({ array, changes, ...rest}) => ({
  array: Object .entries (changes) .reduce ((a, [k, vs], _, __, index = array [0] .indexOf (k)) =>
    vs.reduce(
      (a, v, i) =>
        (i + 1) in a
          ? update ((i + 1), update (index, v, a [i + 1] ), a)
          : concat (a, [update (index, v, map (always (''), array [0]) )] ),
      a),
    array
  ),
  ...rest
})

const state = {
  array: [["Name", "Phone", "Email"]], 
  changes: {Email: ["[email protected]","[email protected]"], Name: ['Wilma', 'Fred', 'Betty']}
}

const state2 = addInputToArray (state)

console .log (
  state2
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
<script> const {update, concat, map, always} = R;                    </script>

しかし、それにもかかわらず、それはまだ興味深い問題につながったので、ありがとう!

説明

reduceこのバージョンのパラメータについて質問されたコメント説明するために、私は最初に一歩後退します。私は関数型プログラミングの大ファンです。それには多くの意味と意味がありますが、ここで関連するのは、ステートメントではなく式でできるだけ多く書くことを好むということです。ステートメントのようなfoo = 1、またはif (a) {doB()}彼らがそうでなければ、数学的な方法で進めることができ、分析にタイミングおよびシーケンシングを導入するので、簡単に分析を受けません。

これをサポートするために、可能であれば、かなり複雑な場合でも、本体が単一の式で構成される関数を記述します。私はこれを常に読みやすい方法で行うことはできません。そのような場合は、代わりに読みやすさを選択します。多くの場合、ここで何とかできるので、それをサポートするために、関数にデフォルトのパラメーターを追加して、そうでなければ代入ステートメントになるものをサポートすることがあります。純粋に関数型言語のHaskellには、このような一時的な割り当てに便利な構文があります。

let two = 2; three = 3 
    in two * three  -- 6

Javascriptはそのような構文を提供していません。(または、実際には、構文に問題があり、非推奨になっています。)パラメーターにデフォルト値を指定して変数を追加することは、妥当な回避です。これにより、ローカル変数を定義するのと同じことを実行して、式の繰り返しを回避できます。

これがあった場合:

const foo = (x) =>
  (x + 1) * (x + 1) 

ここで繰り返し計算を行います(x + 1)。明らかにここではマイナーですが、他の場合には高価になる可能性があるので、この置換を書くかもしれません:

const foo = (x) => {
  const next = x + 1
  return next * next
}

しかし、今では複数のステートメントがあります。可能な場合は避けたいものです。代わりに、次のように記述します。

const foo = (x, next = x + 1) =>
  next * next

繰り返される計算は保存しますが、コードはより簡単な分析の影響を受けやすくなります。(これらの単純なケースでは、分析はまだ簡単ですが、これがどのように複雑になるかを想像するのは簡単です。)

実際の問題に戻ります。私は次のようなコードを書きました:

<expression1> .reduce ((a, [k, vs], _, __, index = array [0] .indexOf (k)) => <expression2>

ご指摘のとおりArray.prototype.reduce、アキュムレータ、現在の値、現在のインデックス、および初期配列の最大4つのパラメータを取ります。index何度も計算したり一時変数を追加したりしないように、新しいデフォルトパラメータとして追加します。しかし、現在のインデックスや初期配列は気にしません。これを((a, [k, vs], ci, ia, index = <expression>)(「現在のインデックス」を表す「ci」と「初期配列」を表す「ia」を使用して)または同様のものとして記述できますindex5番目のパラメーターとして追加する場合は、これらを指定する必要がありますが、気にしません。これらの変数は使用しません。

パターンマッチング構文を使用する一部の言語では、ここで有用なプレースホルダーとしてアンダースコアが提供され、呼び出し元によって提供されたが使用されていない変数を表します。JSは構文的にそれをサポートしていませんが、アンダースコア(_)は、それらのペア(__と同様に、有効な変数名です。関数型プログラミングを行う人々は、パターンマッチング言語の場合と同じように関数型プログラミングを使用することがよくあります。彼らは単にここで何かが渡されると発表しますが、私はそれについてもう気にしません。同様の構文機能をJSに追加する提案1があり、それが実現した場合は、代わりにそれを使用する可能性があります。

あなたが見るのであれば_、パラメータとしてか__または(まれ)_1_2_3など、彼らはしばしばJSのプレースホルダの欠如のために簡単な回避策です。_:には他にも用途があります。お気づきとおり、これを使用してプライベートオブジェクトのプロパティにプレフィックスを付ける規則があります。これは、ライブラリアンダースコアおよびそのクローン(成長したlodash)のデフォルトの変数名でもありますしかし、それらの間には混乱の余地はほとんどありません。アンダースコアを関数の引数として渡すことも考えられますが、それを本体の変数として使用することで、意味が明確になるはずです。

(そして、私がもともとこの説明をコメントに書くつもりだったと思うために!)


1興味があれば、さまざまな提案のディスカッション見ることができます

元の回答

基礎となる要件に関する詳細情報がなければ、私は簡単に始めます。この関数はあなたが望むことをするようです:

const addInputToArray = (
  { array, indexes, tempDestination, tempInput, ...rest}, 
  index = indexes[tempDestination]
) => ({
  array: [
    array [0], 
    ...tempInput .map (v => array [0] .map ((s, i) => i == index ? v : ''))
  ],
  indexes,
  ...rest
})

const state = {array: [["Name", "Phone", "Email"]], indexes: {Name: 0, Phone: 1, Email: 2}, tempInput: ["[email protected]","[email protected]"], tempDestination: "Email"}

console .log (
  addInputToArray(state)
)

しかし、まだ表明されていない要件が他にもあることに気付いても驚かないでしょう。このバージョンでは、最初から追加要素を構築し、あなたが異なると、再びそれを呼び出したいかもしれないと思わtempInputtempDestinationし、それらに追加します。その場合、これは機能しません。しかし、それは良い出発点として役立つかもしれません。

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

Ramdaを使用して入力配列に述語をマッピングして2つの配列を取得する方法

分類Dev

Ramdaを使用して配列の配列をオブジェクトの配列に変換する方法は?

分類Dev

配列Ramdaに新しいオブジェクトを挿入します

分類Dev

Ramda.jsを理解する

分類Dev

配列値のRamdaパス

分類Dev

高度なRamda配列変換

分類Dev

Ramdaを使用してオブジェクトマップを配列に変換する方法は?

分類Dev

ramda js concat the value using reduce

分類Dev

文字列Ramda.jsの末尾に追加

分類Dev

ramdaとramda-fantasyを使用したモナドIO

分類Dev

関数を構成するためにRamda / JSを正しく使用する方法

分類Dev

オブジェクトを配列Aから配列Bに移動します。Ramda.js

分類Dev

ramdaライブラリを使用して2つの配列を組み合わせる方法は?

分類Dev

Ramdaで、配列内の次の値を調べて、次々に繰り返される値を削除する方法

分類Dev

Ramdaを使用して、キー値によって配列内の一致するオブジェクトを見つける方法

分類Dev

RAMDA管内Promise.allを使用して

分類Dev

Ramdaを使用してオブジェクトの配列を単一のオブジェクトにマップする方法

分類Dev

ramda.jsを使用してそれらのオブジェクトから値を抽出する整数の配列にオブジェクトの配列を変換する方法は?

分類Dev

ramdaを使用して各種配列をフラット化

分類Dev

Ramdaを使用して時間形式を解決する方法

分類Dev

Ramda関数の重複を削除する

分類Dev

Ramdaを使用した配列の計算の簡素化

分類Dev

Ramda.js:リストする引数

分類Dev

ramda.jsを使用してオブジェクトの配列内のパスの発生をカウントする方法は?

分類Dev

ramda.jsを使用して、オブジェクトの配列を1つのオブジェクトに変換します

分類Dev

3つの配列をramdaとマージします

分類Dev

Ramda:uniq値のフラット配列を抽出します

分類Dev

Ramdaを使用してネストされたキーに基づいてオブジェクトの配列を並べ替える方法は?

分類Dev

ramda.jsのchain()とmap()の違い

Related 関連記事

  1. 1

    Ramdaを使用して入力配列に述語をマッピングして2つの配列を取得する方法

  2. 2

    Ramdaを使用して配列の配列をオブジェクトの配列に変換する方法は?

  3. 3

    配列Ramdaに新しいオブジェクトを挿入します

  4. 4

    Ramda.jsを理解する

  5. 5

    配列値のRamdaパス

  6. 6

    高度なRamda配列変換

  7. 7

    Ramdaを使用してオブジェクトマップを配列に変換する方法は?

  8. 8

    ramda js concat the value using reduce

  9. 9

    文字列Ramda.jsの末尾に追加

  10. 10

    ramdaとramda-fantasyを使用したモナドIO

  11. 11

    関数を構成するためにRamda / JSを正しく使用する方法

  12. 12

    オブジェクトを配列Aから配列Bに移動します。Ramda.js

  13. 13

    ramdaライブラリを使用して2つの配列を組み合わせる方法は?

  14. 14

    Ramdaで、配列内の次の値を調べて、次々に繰り返される値を削除する方法

  15. 15

    Ramdaを使用して、キー値によって配列内の一致するオブジェクトを見つける方法

  16. 16

    RAMDA管内Promise.allを使用して

  17. 17

    Ramdaを使用してオブジェクトの配列を単一のオブジェクトにマップする方法

  18. 18

    ramda.jsを使用してそれらのオブジェクトから値を抽出する整数の配列にオブジェクトの配列を変換する方法は?

  19. 19

    ramdaを使用して各種配列をフラット化

  20. 20

    Ramdaを使用して時間形式を解決する方法

  21. 21

    Ramda関数の重複を削除する

  22. 22

    Ramdaを使用した配列の計算の簡素化

  23. 23

    Ramda.js:リストする引数

  24. 24

    ramda.jsを使用してオブジェクトの配列内のパスの発生をカウントする方法は?

  25. 25

    ramda.jsを使用して、オブジェクトの配列を1つのオブジェクトに変換します

  26. 26

    3つの配列をramdaとマージします

  27. 27

    Ramda:uniq値のフラット配列を抽出します

  28. 28

    Ramdaを使用してネストされたキーに基づいてオブジェクトの配列を並べ替える方法は?

  29. 29

    ramda.jsのchain()とmap()の違い

ホットタグ

アーカイブ