dポイントプレゼントキャンペーン実施中!

sort関数等調べたのですがうまくできません。
やりたいことは
http://q.hatena.ne.jp/1155090363
↑で見つけた事とそっくりなのですが・・・。
-------------------------------------------

arrItem[n] という配列の一つの要素の中に、
タブで区切られた10個程のデータが入っています。
arrItem[0] = "5 ^ 店名5 ^ 品名5 ^ 価格5 ^ 割引額5 ^・・・^ 備考5"
arrItem[1] = "2 ^ 店名2 ^ 品名2 ^ 価格2 ^ 割引額2 ^・・・^ 備考2"
arrItem[2] = "11 ^ 店名9 ^ 品名9 ^ 価格9 ^ 割引額9 ^・・・^ 備考9"
一列目はSEQ番号でユニークですが、順番が並んでいません。
この配列をSEQ番号で並べ替えたいのですが、
sortだと文字列比較のためか桁数の違う数字の並べ替えが
上手くできません。数値としてのソート方法
が分かる方いらっしゃいましたらご教授願います。

もし可能なら、1列目を数値降順にしたり昇順にしたり、
また2列目を五十音順にソートしたり、
また4列目を価格の安い順にソートしたり
と応用も可能ならばご教授願いたいです。

宜しくお願い致します。

A 回答 (5件)

速度を求めないなら、下記のような感じでしょうか。



var arrItem = new Array;
arrItem[0] = "5 \t あ店名5 \t 品名5 \t 価格5 \t 割引額5 \t・・・\t 備考5";
arrItem[1] = "2 \t い店名2 \t 品名2 \t 価格2 \t 割引額2 \t・・・\t 備考2";
arrItem[2] = "11 \t う店名9 \t 品名9 \t 価格9 \t 割引額9 \t・・・\t 備考9";

/*
//1列目で数値として昇順でソート
arrItem.sort(mySort_0);

//1列目で数値として降順でソート
arrItem.sort(mySort_0_Desc);

//2列目で文字列として昇順でソート
arrItem.sort(mySort_1);

//2列目で文字列として降順でソート
arrItem.sort(mySort_1_Desc);

function mySort_0(a,b){
var aa = a.split("\t")[0];
var bb = b.split("\t")[0];
return aa-bb;
}

function mySort_0_Desc(a,b){
var aa = a.split("\t")[0];
var bb = b.split("\t")[0];
return bb-aa;
}

function mySort_1(a,b){
var aa = a.split("\t")[1];
var bb = b.split("\t")[1];
if(aa > bb) return 1;
if(aa < bb) return -1; //>
return 0;
}

function mySort_1_Desc(a,b){
var aa = a.split("\t")[1];
var bb = b.split("\t")[1];
if(aa > bb) return -1;
if(aa < bb) return 1; //>
return 0;
}


速度を求めるなら、arrItemを分割してから、ソートして、分割したものをくっつけるやり方のほうが早いです。
列指定、並び順等を対応させて…以下のような感じ。

var arrItem=mySort(arrItem,1,false,true);

//引数:
//ソート対象の配列
//ソートする列
//並び順 true:昇順 false:降順
//数値でソートか? true:数値でソート false:文字列としてソート
function mySort(arr,col,odr,num){
var srtArr = new Array();
for(var i=0;i<arr.length;i++) {
var key = arr[i].split("\t")[col];
if(num){
srtArr.push(new Array(key-0,arr[i]));
}else{
srtArr.push(new Array(key,arr[i]));
}
}
if(odr){
srtArr.sort(mySortSub);
}else{
srtArr.sort(mySortSubDesc);
}
var retArr = new Array();
for(var i=0;i<srtArr.length;i++) {
retArr.push(srtArr[i][1]);
}
return retArr;
}

function mySortSub(a,b){
if(a[0] > b[0]) return 1;
if(a[0] < b[0]) return -1; //>
return 0;
}

function mySortSubDesc(a,b){
if(a[0] > b[0]) return -1;
if(a[0] < b[0]) return 1; //>
return 0;
}
    • good
    • 0

ANo.4のふたつめのスクリプトの補足です。


//1列目を数値昇順
var arrItem=mySort(arrItem,0,true,true);

//1列目を数値降順
var arrItem=mySort(arrItem,0,false,true);

//2列目を文字列昇順(五十音順?)
var arrItem=mySort(arrItem,1,true,false);

こんな感じで使用します。
4列目を価格の安い順は…「価格」という文字列が入ってなければ…
var arrItem=mySort(arrItem,3,true,true);
でいけますが…「価格」という文字列が入っていたら、改造しないとだめですね。
って、ちょっとひましてるので、無理やり対応してみました(^^;
割引額のほうもいけます。

//引数:
//ソート対象の配列
//ソートする列
//並び順 true:昇順 false:降順
//数値でソートか? true:数値でソート false:文字列としてソート
function mySort(arr,col,odr,num){
var srtArr = new Array();
for(var i=0;i<arr.length;i++) {
var key = arr[i].split("\t")[col];
if(num){
srtArr.push(new Array(key.replace(/^\D+/,"")-0,arr[i]));
}else{
srtArr.push(new Array(key,arr[i]));
}
}
if(odr){
srtArr.sort(mySortSub);
}else{
srtArr.sort(mySortSubDesc);
}
var retArr = new Array();
for(var i=0;i<srtArr.length;i++) {
retArr.push(srtArr[i][1]);
}
return retArr;
}

function mySortSub(a,b){
if(a[0] > b[0]) return 1;
if(a[0] < b[0]) return -1; //>
return 0;
}

function mySortSubDesc(a,b){
if(a[0] > b[0]) return -1;
if(a[0] < b[0]) return 1; //>
return 0;
}
    • good
    • 0
この回答へのお礼

すごい
ANo.4のふたつめのスクリプト、バッチリです、有難うございます。
価格や割引額の列は数値のみなのでOKです。
わざわざお手数お掛け頂きありがとうございます。
必要になったらこの改造頂いたスクリプトも利用させていただきます。
有難うございました。

お礼日時:2006/10/30 11:59

" ^ "ってタブですよね?


でしたら以下のような感じでいかがでしょうか。

arrItem.sort(comparator);
function comparator(value1, value2) {
var index1 = parseInt(value1.split("\t", 2)[0]);
var index2 = parseInt(value2.split("\t", 2)[0]);
return index1 - index2;
}

ソートの順番や方法は比較関数(上記の場合で言うとcomparator)を色々準備すればよいと思います。
    • good
    • 0

#1さんに補足。


比較関数は数値として扱うだけが能じゃないので、文字列の複雑な比較もできます。
この辺りは友人が実際に書いたコードがあるので引用してしまいます。
--
// 固定長文字列の8文字目からのみを切り出して比較する関数
function nameSort(a, b) {
var as = a.substring(8, 100);
var bs = b.substring(8, 100);
return as > bs ? 1 : as < bs ? -1 : 0;
}
--
可変長なら文字列検索と組み合わせれば比較関数を作れるでしょう。
この方法を使えば文字列配列をそのままソートできますから、#1さんの言うほど泥臭くはないかと。
以下にその呼び出し辺りを抜粋引用。
--
// colorsという配列が用意されているとして
output(colors); // ソートせずに出力
tmp = colors.sort(); output(tmp); // ascii順ソートして出力
tmp = colors.sort(nameSort); output(tmp); // 上で引用した8文字目からのascii順ソート
--
#尚、その友人が書いたWebPage全体については本人に確認が取れないので公開は控えます。悪しからず。
    • good
    • 0
この回答へのお礼

切り出しや文字列検索との組み合わせソート、
参考にして有用な場面で使わせて頂きたいと思います。
有難うございました。

お礼日時:2006/10/27 19:28

自分だったらですが。



とりあえず参考URLに書いてあるのを参考にしますと。

//数値としてソートするときの比較関数、昇順の場合
function SortSet(a,b){return a - b}
document.write("数値Sort = " + data2.sort(SortSet) + "<BR>");
//文字列としてソートすると、
document.write("文字列Sort = " + data2.sort());

となっていますので、まず配列からSEQ番号を全て抜き出して、
また配列を作成し、新たに作成した配列でsort関数を利用して、
昇順に並べ替えます。
そうしたら並べ替えした配列のSEQ番号を配列0から取得し、
並べ替えする前の配列のSEQ番号とつき合わせて同一のSEQ番号を見つけたら、
その内容をさらに新しく作った配列にコピーします。

一応そういう"泥臭い"やり方をすれば可能かと思いますが…。
ただしこのケースだと2列目などのデータではソートできませんね。
店名がかぶるかもしれませんし。

データ自体はファイルから読み込むのか、
DBから取得するのかわからないのですが、
DBから取得するならSQL発行の段階で並べ替えをするほうが、
作り的にはこういった事を考えずにスマートになると思います。
(SQL発行のリスクと、配列入換ロジックのリスクを考える必要はありますが。)

参考URL:http://homepage1.nifty.com/mstak/Computer/javasc …
    • good
    • 0
この回答へのお礼

早々のご回答を有難うございました。
(1).先ずSEQのみの配列を生成しそれをソート
(2).元の配列データと(1)をマッチングして(1)に肉付け
という解釈でよろしいでしょうか。
(2)は要素数×要素数の処理となると要素が数千に及んだ場合ちょっときついかな。(js処理で数千の配列という事自体無理がありますが)
DBが使えればこんな面倒な事しないで済みますね。
他の回答と併せて参考にさせて頂きます、有難うございました。

お礼日時:2006/10/27 19:24

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!