2016-09-05 1 views
3

나는 의회 통화 번호 라이브러리의 정렬과 비교를 단순화하기 위해 자바 스크립트 클래스에서 작업 해왔다. 대부분의 경우 정렬 된 목록을 반환하는 주된 방법 중 하나를 제외하고는 대부분이 작동합니다. 클래스의 다른 메서드를 사용하여 클래스 외부에서 정렬을 수행 할 수 있으므로 sort() 함수를 입력 할 때 왜 범위가 손실되는지 잘 모르겠습니다.나는 사용자 정의 정렬 방법으로 범위 문제가 있다고 생각한다.

범위를 sort()로 전달할 수있는 방법인지 또는 해당 메서드에 대한 액세스 권한이 필요한지 여부는 확실하지 않습니다.

https://gist.github.com/rayvoelker/accaa95c6b5db28f7f84429f8a3d8cdf

여기에 내가 데 클래스 방법입니다 :

나는 것을 증명해야하는 자바 스크립트와 (오류 포함) 클래스의 빠른 HTML 테스트의 github의의 요점을 만들었습니다 문제. 어쩌면 나는 단순해야하는 것을 보지 않고있을뿐입니다. 여기

locCallClass.prototype.localeCompare = function (a, b) { 
    try { 
     var a_norm = this.returnNormLcCall(a), 
      b_norm = this.returnNormLcCall(b); 

      return (a_norm < b_norm ? -1 : (a_norm > b_norm ? 1 : 0)); 
    } 
    catch (err) { 
     // console.log("error") 
    } 
} 

locCallClass.prototype.sortCallNumbers = function (callnumbers) { 
    var sorted = callnumbers.sort(function (a,b) { 
     return this.localeCompare(a,b); 
    }); 

    return sorted; 
} 

그리고

는 내가 전화 했어 방법입니다 :

var loc = new locCallClass(); 
var set1 = ["LC 346 .65 .B29","LC 346 .M634","HX 754 .5 .C15","HX 754 .C7723"]; 

var sorted = loc.sortCallNumbers(set1); 

그리고 여기에 요점에서 같은 데모 코드의 조각이다 :

// js-loc-callnumbers 
 
// A javascript class to normalize and perform various sorting options on 
 
// Library of Congress Call Numbers within a library institution. 
 

 
function locCallClass() { 
 
\t // the regular expression that defines the Library of 
 
\t // Congress call number. Thanks to Bill Dueber's post on the subject for the regex 
 
\t // http://robotlibrarian.billdueber.com/2008/11/normalizing-loc-call-numbers-for-sorting/ 
 
\t this.lc = /^\s*([A-Z]{1,3})\s*(\d+(?:\s*\.\s*\d+)?)?\s*(?:\.?\s*([A-Z]+)\s*(\d+)?)?(?:\.?\s*([A-Z]+)\s*(\d+)?)?\s*(.*?)\s*$/; 
 
\t 
 
\t //local storage for an array of call numbers 
 
\t this.callNumberArray = []; 
 
\t //a mostly sorted array of call numbers for testing 
 
\t this.testCallNumbers = ["Z10.1 A", "Z5.1 A", "CB3 .C55", "CS418 .J82", "CS425 .B95", "D21 .W93", "D21.1.D58 1981", "D761 .W54", "D761.9.F7 G8", "DA86 .P884", "DA86 .R52", "DA506.A2 A4", "DA506.A2 B75", "DA784.5 .M23 1989", "DA785 .S12", "DC129 .W6", "DC130.A2 H3", "DF623 .C46", "DF631 .B313", "DK 267 .W78", "DK268.A1D56213 1999", "DS 70.7 .O6", "DS 70.7 .S27", "DS557.C28S6", "DS 557 .F3", "DS 917 .W47", "DS 917.35 .P33", "DT 636 .S5 A3", "DT636.2.F65 1996", "E 160 .F72", "E 160 .F73", "E184.A1I444 1992", "E184.A1I445 1996", "E 302 .J442 1984", "E302.J442 2004B", "E 487 .C746", "E 487 .C746 1966", "E 876 .U84 1986", "E 876 .V53", "F548.9.N4R437 2005", "F548.9.N4S77 2007", "F 1656 .C7 1968", "F 1659 .B55 F4", "GN 51 .A58", "GN 51 .A58 1988B", "GV 741 .B56", "GV741 .I58", "Q183.9.I34 2002", "Q183.9.L45 1993", "QA 29 .P775 A3 1987", "QA29.R3A4 1995", "QA 76.758 .H86 1989", "QA76.758.K365 2008", "QA 164 .C63 1969", "QA 164 .C63 1969", "QA274.73.R84 2004", "QA274.73.S2813 1999", "QA 353 .E5 Z4313 1993", "QA 353 .G44 W55 1990", "QA 640.7 .B55 1970", "QA641.A587 1996", "QC 173.98 .M44 V.1", "QC 173.98 .M44 V.1", "QD 21 .C51", "QD 21 .C51", "QD501 .B242 V.37", "QD501.B242 V.38", "QH 81 .B73", "QH 81 .B754", "QH540.I5", "QH540.I5", "QK 314 .F54", "QK 321 .A3613", "QL951 .C8", "QL951 .C8", "QP 601 .C733 V.171", "QP 601 .C733 V.172", "RA 410.7 .C5", "RA 410.7 .E73", "RC455.S8 1961", "RC 455 .S928", "RD 98 .G38", "RD 99 .E42 1955", "S 942 .C6 1974", "S 942 .K63 1972", "TA166.W68 1980", "TA167.A965 1998", "TA1520.S87 2007", "TA1520.W35 1998", "TD 741 .I33", "TD 741 .I33 1956", "TJ163.2 .A55", "TJ163.2 .A55", "TK5105.875.I57G723 2005", "TK5105.875.I57H338 1996", "TL215.J58L35 2005", "TL215.M18D53 2005", "TP155.C69 V.5 1997", "TP 155 .C74 1986", "TS156 .I838 2003", "TS 156 .J324"]; 
 
} 
 

 
// locCallClass.returnNormLcCall(call_number) 
 
// returns a "normalized" call number 
 
locCallClass.prototype.returnNormLcCall = function(call_number) { 
 
\t var result = this.lc.exec(call_number); 
 
\t if (!result) { 
 
\t \t throw new Error(call_number + " Not a Call Number"); \t \t 
 
\t } 
 
\t 
 
\t // track the position of what we're looking at in the callnumber 
 
\t var before_first_cutter = true; 
 
\t var return_string = ""; 
 
\t 
 
\t // work through the results starting at 1 (the 0 value in the array is the original input) 
 
\t for(var i=1; i<=(result.length-1); i++) { 
 
\t \t if (i>1) { 
 
\t \t \t return_string = return_string + "." 
 
\t \t } 
 
\t \t 
 
\t \t if (i>2) { 
 
\t \t \t before_first_cutter = false; 
 
\t \t } 
 
\t \t 
 
\t \t return_string = return_string + this.padZed(result[i], before_first_cutter); 
 
\t } \t \t 
 
\t 
 
\t // TODO: consider adding further checks to see if the return string 
 
\t // consists of 8 segments 9 characters and throw an error if not 
 
\t return return_string; 
 
} 
 

 
// locCallClass.localeCompare(b,a) 
 
// replicates functionality of the normal compare function 
 
// so that it may be used in external sorting operations: 
 
// 
 
// A negative number if the reference string (a) occurs before the 
 
// given string (b); 
 
// positive if the reference string (a) occurs after 
 
// the compare string (b); 
 
// 0 if they are equivalent. 
 
locCallClass.prototype.localeCompare = function (a, b) { 
 
\t try { 
 
\t \t var a_norm = this.returnNormLcCall(a), 
 
\t \t \t b_norm = this.returnNormLcCall(b); 
 
\t \t \t \t \t \t 
 
\t \t \t return (a_norm < b_norm ? -1 : (a_norm > b_norm ? 1 : 0)); 
 
\t } 
 
\t catch (err) { 
 
\t \t // console.log("error") 
 
\t } 
 
} 
 

 
// locCallClass.sortCallNumbers() 
 
// takes a variable list of call numbers as arguments, and returns 
 
// a sorted array of call numbers in their original format/ 
 
// You can also use this method with an array like the following: 
 
// loc.sortCallNumbers.call(loc_instance,input) 
 
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters 
 
// 
 
// TODO: Consider removing this method, instead using something like the 
 
// following: 
 
// var loc = new locCallClass(); 
 
// loc.testCallNumbers.sort(function(a,b) {return loc.localeCompare(a,b)}); 
 
locCallClass.prototype.sortCallNumbers = function (callnumbers) { 
 
\t var sorted = callnumbers.sort(function (a,b) { 
 
\t \t return this.localeCompare(a,b); 
 
\t }); 
 
\t 
 
\t return sorted; 
 
} 
 

 
// locCallClass.isBetween(a,b,c) 
 
// returns true if a <= c <= b 
 
locCallClass.prototype.isBetween = function (a,b,c) { 
 
\t //this.localeCompare(a, b) <= 0 if in sort order \t 
 
\t return ((this.localeCompare(a,c) <= 0 && this.localeCompare(c,b) <=0) ? true : false); 
 
} 
 

 
// locCallClass.padZed() 
 
// returns portion of the call number padded out to enable sorting. 
 
locCallClass.prototype.padZed = function (value, before_first_cutter) { 
 
\t //pad value with zeros - return value will have a length of 9 
 
\t // The exceptions here are going to be if the number is before the 
 
\t // cutter, then we should treat it as two different parts: whole 
 
\t // number, and decimal portion. 
 

 
\t if(value) { 
 
\t \t if(before_first_cutter && !isNaN(value)) { 
 
\t \t \t //this is a number before the first cutter, split it, and then 
 
\t \t \t // pad each of the parts 
 
\t \t \t var int_portion = Math.floor(value).toString(); 
 
\t \t \t var dec_portion = (value % 1).toFixed(3).toString().substr(2,3); 
 
\t \t \t var pad_zeros = ""; 
 
\t \t \t 
 
\t \t \t for (var i=0; i<(9 - int_portion.length); i++) { 
 
\t \t \t \t pad_zeros = pad_zeros + "0"; 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t return_value = pad_zeros + int_portion; 
 
\t \t \t 
 
\t \t \t var pad_zeros = ""; 
 
\t \t \t for (var i=0; i<(9 - dec_portion.length); i++) { 
 
\t \t \t \t pad_zeros = pad_zeros + "0"; 
 
\t \t \t } 
 
\t \t \t 
 
\t \t \t return_value += "." + dec_portion + pad_zeros; 
 
\t \t \t return return_value; 
 
\t \t } // end if 
 
\t 
 
\t \t else { 
 
\t \t \t //pad the value to the right 
 
\t \t \t var pad_zeros = ""; 
 
\t \t \t for (var i=0; i<(9 - value.length); i++) { 
 
\t \t \t \t pad_zeros = pad_zeros + "0"; 
 
\t \t \t } 
 

 
\t \t \t return value + pad_zeros; 
 
\t \t } 
 
\t } 
 
\t 
 
\t else { 
 
\t \t return "000000000"; 
 
\t } 
 
} 
 

 

 
/* test script */ 
 

 
var loc = new locCallClass(); 
 

 
var output1 = document.getElementById("output1"); 
 

 
// define, show and then sort the first set 
 
var set1 = ["LC 346 .65 .B29", 
 
      "LC 346 .M634", \t \t 
 
      "HX 754 .5 .C15", 
 
      "HX 754 .C7723" 
 
      ]; 
 
output1.innerHTML = "<b>pre-sort</b><br>"; 
 
for(var i=0; i<set1.length; i++) { 
 
    output1.innerHTML += set1[i] + "<br>"; 
 
} 
 

 
//sort with the specialized sort method from our class, "loc" 
 
var sorted1 = set1.sort(function(a,b) { 
 
    return loc.localeCompare(a,b); 
 
}); 
 

 
output1.innerHTML += "<hr><b>sorted</b><br>"; 
 

 
for(var i=0; i<sorted1.length; i++) { 
 
    output1.innerHTML += sorted1[i] + "<br>"; 
 
} 
 

 
// now test the built in method to sort call numbers 
 
// which doesn't work for some reason 
 
var alt_sorted = loc.sortCallNumbers(set1);
<!DOCTYPE html> 
 
<html> 
 
<head> 
 
\t <meta charset="utf-8"> 
 
\t <title>locCallClass test sorting of call numbers</title> 
 
</head> 
 

 
<body style="font-family:monospace;"> 
 

 
\t <h3>test sorting of call numbers</h3> 
 
\t 
 
\t <div id="output1"></div> 
 
\t \t 
 
</body>

나를 도울 수있는 사람에게 미리 감사드립니다!

답변

2

캐시 this : this

locCallClass.prototype.sortCallNumbers = function(callnumbers) { 
    var self = this; 
    var sorted = callnumbers.sort(function(a, b) { 
    return self.localeCompare(a, b); 
    }); 

    return sorted; 
} 

또는 하드 바인딩 종류의 콜백 함수 :

locCallClass.prototype.sortCallNumbers = function(callnumbers) { 
    var sorted = callnumbers.sort(function(a, b) { 
    return this.localeCompare(a, b); 
    }.bind(this)); 

    return sorted; 
} 
+0

이 좋아, 그래 ... 나는이에 대한 간단한 해결책이있을 줄 알았어. 도와 줘서 고마워! 이 상황에서 바인딩하거나 캐시해야하는 간단한 이유가 있습니까? –

+1

'this'는 js에서 어떻게 든 환상적입니다. 그러나 정말로 이해하기가 어렵지는 않습니다. 전체 내용은 여기에 있습니다 : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this – dNitro

관련 문제