Help us understand the problem. What is going on with this article?

vue.jsでcsvファイルのデータ抽出表示とオセロ

More than 3 years have passed since last update.

エクセルなどで使われるCSVファイルをブラウザで表示して見るツール
デモ:http://pie.karou.jp/zf.html

index.png

サンプルとして郵便番号と住所の書いてあるcsvファイルが
ちょうどよいので”郵便番号 csv”で検索してダウンロードする

全国のデータ KEN_ALL_ROME.CSV 10.5MB
"0640941","北海道","札幌市 中央区","旭ケ丘","HOKKAIDO","SAPPORO SHI CHUO KU","ASAHIGAOKA"
1行がこんな感じで 12万行


  1. csvファイルをinput fileで選択する
  2. csvファイルはshiftJISが多くて文字化けするのでライブラリencoding.jsを使って対策する
  3. 12万行も表示できないので30行だけ表示する(ファイルを開くのに5秒くらい)
  4. and検索をするために

    Array.filter(function(v){
    return v.join("").indexOf("東京")>-1);
    }).filter(function(v){
    return v.join("").indexOf("新宿")>-1);
    });
    

    これでデータ抽出すると1秒以下で697件見つけて表示される


<!doctype html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>csvファイル検索ツール</title>
<style>
h1{font-size: 16px;display:inline;}
p{display:inline;}
input[type=number]{width:80px;}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.min.js"></script>
<script src="folder3/encoding.min.js"></script>
</head>
<body>
<div id="app">
   <h1>csvファイル 検索ツール(簡易オートフィルタ)</h1>
   <input type="file" @change="fileChange">
   <p>列幅調整はセル内でBackspace,←,→キー</p>
   <hr>
   検索文字:<input type="text" id="filter1">and<input type="text" id="filter2">
   行:<input type="number" id="maxGyou" step="10" min="10" value="30">
   <input type="button" @click="filterFn" value="抽出">
   ページ:
   <select v-model="index">
     <option v-for="n in pageLength" v-bind:value="n">{{n}} </option>
   </select> /{{ (pageLength==100)?"over": pageLength}}
   <input type="button" value="←" @click="plus(-1)">
   <input type="button" value="→" @click="plus(1)">
   一致数:{{ matchNum }}
   <hr>
   <div v-for="n in gyouNum" style="white-space: nowrap;">
      <input type="text" v-for="(v,i) in csvData[(index-1)*gyouNum + (n-1)]" :value="v" 
      @keyup.left="css(i,-25)" @keyup.right="css(i,50)" @keyup.delete="css(i,-1000)" 
      :style="{color : (colorArr[i] || 'black'), width: (widthArr[i] || 150) + 'px' }" readonly="readonly">
   </div>
</div>
<script>
var vm = new Vue({
   el: '#app',
   data: {
      index: 1,
      gyouNum: 30,
      fileData: [],
      csvData: [],
      widthArr: [],
      colorArr: [],
      matchNum: 0,
   },
   computed: {
      pageLength: function() {
         return Math.ceil(this.csvData.length / this.gyouNum);
      },
   },
   methods: {
      fileChange: function(e) {
         $("#filter1,#filter2").val("");
         var file = e.target.files[0];
         var reader = new FileReader();
         reader.onload = function(e) {
            var codes = new Uint8Array(e.target.result);
            var encoding = Encoding.detect(codes);
            var unicodeString = Encoding.convert(codes, {
               to: 'unicode',
               from: encoding,
               type: 'string'
            });
            var arr = unicodeString.trim().replace(/\"/g, "").split("\n");
            vm.fileData = arr.map(v => v.split(","));
            vm.filterFn();
         };
         reader.readAsArrayBuffer(file);
      },
      plus: function(x) {
         if (this.index + x <= 0 || this.index + x > this.pageLength) return;
         this.index += x;
      },
      css: function(x, y) {
         this.widthArr[x] = this.widthArr[x] || 150;
         this.widthArr[x] += y;
         if (this.widthArr[x] < 15) {
            this.widthArr[x] = 10;
            this.colorArr[x] = "white";
         } else {
            this.colorArr[x] = "black";
         }
         this.colorArr.push();
         this.widthArr.push();
      },
      filterFn: function() {
         this.index = 1;
         this.gyouNum = $("#maxGyou").val() - 0;
         var filter1 = $("#filter1").val().toLowerCase();
         var filter2 = $("#filter2").val().toLowerCase();
         var arr = this.fileData.filter(function(v) {
            return v.join("").toLowerCase().indexOf(filter1) > -1;
         }).filter(function(v, i) {
            return v.join("").toLowerCase().indexOf(filter2) > -1;
         });
         this.matchNum = arr.length;
         this.csvData = arr.filter(function(v, i) {
            return i < vm.gyouNum * 100;
         });
      },
   },
});
</script>
</body>
</html>


vue.jsで書いたオセロ
https://jsfiddle.net/af9b4bq3/

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.7/vue.min.js"></script>
<p>オセロ</p>
<div id="app">
  <p>白:{{ w }}, 黒:{{ b }}</p>
  <p>{{ ["白","黒"][wb] }}の手番</p>
  <div v-for="i in 8" class="container">
    <div v-for="j in 8" class="waku">
      <div :class="{ 'white': xy[i][j]==0, 'black': xy[i][j]==1 }" @click="oku(i, j)"></div>
    </div>
  </div>
  <p>
    <button @click="pass">pass</button>
  </p>
</div>
p {
  text-align: center;
}
div {
  min-width: 35px;
  min-height: 35px;
}
.container {
  display: flex;
  justify-content: center;
}
.waku {
  border: 1px solid black;
  background-color: green;
}
.white {
  border-radius: 35px;
  background-color: white;
}
.black {
  border-radius: 35px;
  background-color: black;
}
var vm = new Vue({
  el: '#app',
  data: {
    wb: 1,
    xy: [
      [3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 2, 2, 2, 0, 1, 2, 2, 2, 3],
      [3, 2, 2, 2, 1, 0, 2, 2, 2, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 2, 2, 2, 2, 2, 2, 2, 2, 3],
      [3, 3, 3, 3, 3, 3, 3, 3, 3, 3],
    ],
  },
  computed: {
    w: function() {
      return (this.xy.join('').match(/0/g) || []).length;
    },
    b: function() {
      return (this.xy.join('').match(/1/g) || []).length;
    },
  },
  methods: {
    oku: function(x, y) {
      if (this.xy[x][y] != 2) return;
      var flag = false;
      for (var dx = -1; dx <= 1; dx++) {
        for (var dy = -1; dy <= 1; dy++) {
          if (dx == 0 && dy == 0) continue;
          var k = 1;
          while (this.xy[x + k * dx][y + k * dy] <= 1) {
            if (this.xy[x + k * dx][y + k * dy] == this.wb) {
              k = 1;
              while (this.xy[x + k * dx][y + k * dy] == 1 - this.wb) {
                flag = true;
                this.xy[x + k * dx][y + k * dy] = this.wb;
                k++;
              }
              break;
            }
            k++;
          }
        }
      }
      if (flag == false) return;
      this.xy[x][y] = this.wb;
      this.wb = 1 - this.wb;
      this.xy.push();
    },
    pass: function() {
      this.wb = 1 - this.wb;
    },
  },
});
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away