如何使用 Ramda 從 Nested Array 取得值 ?

實務上另外一個常見的 Nested Array 使用 chain() 的範例。

Version

VS Code 1.32.3

Quokka 1.0.195

Ramda 0.26.1

pipe()

import { pipe, prop, map, pluck } from 'ramda';

const data = {
  books: [
    { title: 'Secrets of the JavaScript Ninja',
      authors: [
        { name: 'John Resig' },
        { name: 'Bear Bibeault' }
      ]
    },
    { title: 'RxJS in Action',
      authors: [
        { name: 'Paul P.Daniels' },
        { name: 'Luis Atencio' }
      ]
    }
  ]
};

// getAuthors :: {[a[b]]} -> [b]
const getAuthors = pipe(
  prop('books'),
  map(prop('authors')),
  map(pluck('name'))
);

const result = getAuthors(data);
console.dir(result);

data 為 nested array,想將所有書的 author 抓出來,只有一層 array。

[ 'John Resig', 
  'Bear Bibeault', 
  'Paul P.Daniels', 
  'Luis Atencio' ]

希望結果如上。

// getAuthors :: {[a[b]]} -> [b]
const getAuthors = pipe(
  prop('books'),
  map(prop('authors')),
  map(pluck('name'))
);

由於是多層 array,直接會先用 prop('books') 抓到資料,再使用兩次 map()

但結果是兩層 array,跟我們預期的一層 array 不同。

unnest()

import { pipe, prop, map, pluck, compose, unnest } from 'ramda';

const data = {
  books: [
    { title: 'Secrets of the JavaScript Ninja',
      authors: [
        { name: 'John Resig' },
        { name: 'Bear Bibeault' }
      ]
    },
    { title: 'RxJS in Action',
      authors: [
        { name: 'Paul P.Daniels' },
        { name: 'Luis Atencio' }
      ]
    }
  ]
};

// getAuthors :: {[a[b]]} -> [b]
const getAuthors = pipe(
  prop('books'),
  compose(unnest, map(prop('authors'))),
  pluck('name')
);

const result = getAuthors(data);
console.dir(result);

可先使用 unnest() 攤平一層 array,再使用 pluck() ,如此只剩下一層 array,這正是我們要的結果。

chain()

import { pipe, prop, pluck, chain } from 'ramda';

const data = {
  books: [
    { title: 'Secrets of the JavaScript Ninja',
      authors: [
        { name: 'John Resig' },
        { name: 'Bear Bibeault' }
      ]
    },
    { title: 'RxJS in Action',
      authors: [
        { name: 'Paul P.Daniels' },
        { name: 'Luis Atencio' }
      ]
    }
  ]
};

// getAuthors :: {[a[b]]} -> [b]
const getAuthors = pipe(
  prop('books'),
  chain(prop('authors')),
  pluck('name')
);

const result = getAuthors(data);
console.dir(result);

compose(unnest, map) 相當於 chain() ,可使用 chain() 加以化簡。

Conclusion

  • 只要是多層 array,使用 chain() 的機會就很高,若一時看不出來,可先使用 map() ,發現多了一層,再使用 unnest() ,當看到 compose(unnest, map) 時,就會想到使用 chain() 替換

Reference

Ramda , pipe()

Ramda , prop()

Ramda , map()

Ramda , pluck()

Ramda , compose()

Ramda , unnest()

Ramda , chain()

我来评几句
登录后评论

已发表评论数()

相关站点

+订阅
热门文章