javascriptで使えそうな自分用の関数をまとめてみた。

#はじめに
こちらはネットに落ちているものや自分が学習したものを改良して作ったものになります。
至らないコードもありますがご了承ください。

##配列から要素を排除する関数

```javascript
function unique(array) {
  return array.reduce((prev, number) => {
    if (prev.find(check_num => check_num === number) === undefined) {
      prev.push(number);
    }
    return prev;
  }, []);
}
const duplicationArray = [1,2,3,3,4,4,5,7,6,2,6]; 
console.log(unique(duplicationArray));
// [1, 2, 3, 4, 5, 7, 6] 

```
####流れをざっくりと説明
prevの中に配列の要素が見当たらなければprevにpush。
prevに入っている値と同じものがあったらpushせずにそのままprevを返す

####追記(2020/2.11)
上記のコードについて@ttatsfさんにレビューをしてもらいました！
ありがたい。。コメントをご確認ください！！


##2重配列からオブジェクトの配列に変換

```javascript

function ObjInArray(ArrayInArray, callback) {
  return ArrayInArray.map(callback);
}
const points = [
  [4, 5],
  [10, 1],
  [20, 5]
];
pointsArray = ObjInArray(points, ([x, y]) => { return {x, y};})
console.log(pointsArray);
// 0: {x: 4, y: 5}
// 1: {x: 10, y: 1}
// 2: {x: 20, y: 5}

```
####流れをざっくりと説明
ぱっとみただけでは難しいと思われる。
アロー関数、分割代入。オブジェクトリテラルの機能を使って省略して記述しています。
省略せずにcallback関数の中身を展開すると下記のようになります。
分かりやすさでいうとこちらの方がわかると思います。

```javascript

pointsArray = ObjInArray(points, function(value) { 
                const x = value[0];
                const y = value[1];
                return {x: x, y: y};
              });
                 
console.log(pointsArray);
// 0: {x: 4, y: 5}
// 1: {x: 10, y: 1}
// 2: {x: 20, y: 5}

```

####追記(2020/2.11)
上記のコードについて@ttatsfさんにレビューをしてもらいました！
より良いコードがコメントにありますのでご確認ください！！

##条件に指定した要素以外で配列を新しく作る

```javascript

function reject(array, callback){
  return array.filter(value => !callback(value));
}

const nums = [10, 20, 15, 40];
console.log(reject(nums, value => value < 20))
// [20, 40]

const foods = ["肉", "野菜", "白ご飯", "デザート"];
console.log(reject(foods, value => value === "デザート"))
// ["肉", "野菜", "白ご飯"]

```

####流れをざっくりと説明
filterでは配列要素を繰り返す中で条件に一致した『true』となるもので新しく配列を作成するのですが、そのコールバック関数の真偽値を『！』でひっくり返したことで『false』となる要素で新しい配列を構成するようにしています。

##文字列型にして逆順にして返すメソッドを追加

```javascript

function reverseString(str) {
  return str.split("").reverse().join("");
}

const name = "tanaka";
console.log(reverseString(name))
// akanat

```
####流れをざっくりと説明
reverse()を使うために一旦配列にする。
reverse()で反転させる。
そしてjoinで文字列にして結合させる。

##検索したい文字列があるか検索する

```javascript

const bookShop = {
  books: [{
      title: "ハリーポッター",
      price: 1000,
      quantity: 3,
      author: "tanaka"
    },
    {
      title: "ハレルヤ",
      price: 2000,
      quantity: 2,
      author: "otsuka"
    }
  ],
  serchBookTitles: []
};


const serchForBook = (bookShop, serchText) => {
  bookShop.serchBookTitles = [];
  const filterBooks = bookShop.books.filter(book => {
    if (book.title.indexOf(serchText) === 0 && serchText) { // 検索した文字が先頭にある　&& 空文字でない時
      return bookShop.serchBookTitles.push(book.title);
    }
  });
  if (!filterBooks.length) { //何もないなら配列の中身をリセット
    bookShop.serchBookTitles = [];
  }
};
serchForBook(bookShop, "ハ");
console.log(bookShop.serchBookTitles); //(2) ["ハリーポッター", "ハレルヤ"]
```
####コードの想定（適当に作っているので細かいところは無視してください。。）

・serchForBookの関数の第一引数に検索したいものに関するオブジェクトを入れる。
・serchForBookの関数の第二引数に検索したい文字列を入れる。

```javascript

// もし検索したい文字列の位置を気にせずに含まれているかを調べたい時は条件をこのように変更する。
if (book.title.indexOf(serchText) !== -1 && serchText) {
  return state.serchBooks.push(book);
}
```
##アンカーリンクのスクロール機能

```javascript

  // ヘッダーの高さを測る
  const headerHeightDiff = ()=> {
    const header = document.getElementById('header');
    return headerHeight = header.offsetHeight
  };

  // bodyにヘッダー高さを与える（高階関数を使ってみた）
  const bodyPaddingTop = HeightDiff => unit => body.style.paddingTop = HeightDiff() + unit;
  bodyPaddingTop(headerHeightDiff)("px");
  
  // アンカーリンクのターゲットとなる高さを取得
  const anchorTargetTopPos = (e) =>{
    const href = e.currentTarget.getAttribute('href');
    const targetID = href.slice(1);
    const target = document.getElementById(targetID);
    const elemY = target.getBoundingClientRect().top;
    const scrollY = window.pageYOffset;
    return elemY - scrollY - headerHeightDiff();
  } 

  // セレクターの取得
  const anchorlinks = link => document.querySelectorAll(link)

  // クリック後のスクロール
  anchorlinks('a[href^="#"]').forEach(link => {
    link.addEventListener('click', (e) => {
      e.preventDefault();
      window.scroll({
        top: anchorTargetTopPos(e),
        behavior: 'smooth' 
      });
    });
  });

```


スクロールさせるまでに至る機能を関数でまとめてみた。
これがいいものなのかや改善点はよくわかってないですがもっとスッキリしたらいいんですが。。

#最後に

色々まとめてみました。
もっとこう書くべきとか、実務ではこんなことを使うよというのがあれば是非教えてください。
よろしくお願いいたします。

####追記(2020/2.11)
コメントにいただいたObjInArrayの処理をアロー関数から通常の処理に戻して自分で内部処理がわかるようにメモとして残しています。。

```javascript

function labelValues(...labels){
  return function(xs){
    return xs.map(function(e){
      return labels.reduce(function(acc, label, i) {
        return ({...acc,[label]: e[i]})
      }, {})
    });
  }
};
```