2

親愛なる StackOverflowers…</p>

私は一連の投稿を持っています:

const posts = [
  { title: 'post1', tags: ['all', 'half', 'third', 'quarter', 'sixth']},
  { title: 'post2', tags: ['all', 'half', 'third', 'quarter', 'sixth']},
  { title: 'post3', tags: ['all', 'half', 'third', 'quarter']},
  { title: 'post4', tags: ['all', 'half', 'third']},
  { title: 'post5', tags: ['all', 'half']},
  { title: 'post6', tags: ['all', 'half']},
  { title: 'post7', tags: ['all']},
  { title: 'post8', tags: ['all']},
  { title: 'post9', tags: ['all']},
  { title: 'post10', tags: ['all']},
  { title: 'post11', tags: ['all']},
  { title: 'post12', tags: ['all']}
];

そして、増え続けるユーティリティ関数のセット:

const map = f => list => list.map(f);
const filter = f => list => list.filter(f);
const reduce = f => y => xs => xs.reduce((y,x)=> f(y)(x), y);
const pipe = (fn,...fns) => (...args) => fns.reduce( (acc, f) => f(acc), fn(...args));
const comp = (...fns) => pipe(...fns.reverse()); //  const comp = (f, g) => x => f(g(x));
const prop = prop => obj => obj[prop];
const propEq = v => p => obj => prop(p)(obj) === v;
const flatten = reduce(y=> x=> y.concat(Array.isArray(x) ? flatten (x) : x)) ([]);
const unique = list => list.filter((v, i, a) => a.indexOf(v) === i);
const add = a => b => a + b;
const addO = a => b => Object.assign(a, b);
const log = x => console.log(x);

そして、データを次の形式に変換したいと思います。

[
 { title: 'sixth', posts: [array of post objects that all have tag 'sixth'] },
 { title: 'quarter', posts: [array of post objects that all have tag 'quarter'] },
 { title: 'third', posts: [array of post objects that all have tag ’third'] },
 etc...
]

再利用可能なコンパクトなユーティリティ機能だけを利用して、ポイントフリースタイルを使用します。

すべての投稿から一意のタグを取得できます。

const tagsFor = comp(
  unique,
  flatten,
  map(prop('tags'))
);

tagsFor(posts);

そして、マップとフィルターを使用して、私が望むものを達成する方法を考え出すことができます:

tagsFor(posts).map(function(tag) {
  return {
    title: tag,
    posts: posts.filter(function(post) {
      return post.tags.some(t => t === tag);
    });
  };
});

暗黙のうちにこれを達成することに頭を悩ませているようには見えません。

任意のポインタは、感謝して受信されます...

4

2 に答える 2

1

@naomik に再構築を、@Berghi に組み合わせ論理のうさぎの穴に私を導いてくれたことに感謝します。これが私が思いついたものです…</p>

まず、tagsFor は、いくつかのネストされた配列のすべての一意のエントリを単一の配列に収集します。これは、特定の問題に固有のものではなく、一般的な機能のように聞こえるので、次のように書き直しました。

const collectUniq = (p) => comp( // is this what flatMap does?
  uniq,
  flatten,
  map(prop(p))
);

したがって、@ naomikの入力を取得すると、次のようになります。

const hasTag = tag => comp(  // somePropEq?
  some(eq(tag)),
  prop('tags')
);


const makeTag = files => tag => ({
  title: tag,
  posts: filter (hasTag(tag)) (files)
});


const buildTags = comp(
  map(makeTag(posts)),
  collectUniq('tags')
);

暗黙の解決策の問題は、データ (投稿) が map の makeTag に埋め込まれていることです。

SKI 計算と BCKW ロジックは、組み合わせロジック関数の便利なセットを提供します。

const I = x => x;                       // id
const B = f => g => x => f(g(x));       // compose <$> 
const K = x => y => x;                  // pure
const C = f => x => y => f(y)(x);       // flip
const W = f => x => f(x)(x);            // join
const S = f => g => x => f(x)(g(x));    // sub <*>

これらを id、comp、pure、flip などにエイリアスできます。

それでは、B (作成) で投稿を掘り出しましょう。

const buildTags = comp(
  B(map, makeTag)(posts),
  collectUniq('tags')
);

これで、f(x)(g(x)) の形式であることがわかります。ここで、f = B(map, makeTag); g = collectUniq('タグ'); x = 投稿:

const buildTags = S(B(map)(makeTag))(collectUniq('tags'));

今では暗黙的で宣言的で、簡単に理解できます(とにかく私の心には)

そうだ、誰か私に 3 日かかったビールをくれ!(痛い)

于 2016-10-08T06:44:09.013 に答える