Javascript 根据用户输入自定义排序功能
Javascript custom sort function depending on user input
我正在尝试为 Javascript array.sort
方法制作自定义比较回调函数。它应该 return 一个取决于用户输入的值。
调用该回调函数时,它应该等到用户单击按钮。根据单击的按钮,该函数将知道两个元素中哪个更大以及 return 相应的结果(1 或 -1)。
我知道等待用户输入的唯一方法是使用事件侦听器函数,但我不知道如何使它适应我必须传递给 array.sort()
方法的自定义函数。
这是我正在尝试的代码;我知道这段代码行不通:
var array=["a","b","c"];
array.sort(function(a,b){
var result;
$("#button1").click(function(){
result = 1;
});
$("#button2").click(function(){
result = -1;
});
return result;
}
我开始认为不可能将 array.sort
函数用于此目的。
有办法吗?
您可以通过使用 window.confirm 方法以丑陋的方式执行此操作,该方法的行为是等待您的代码的进一步执行,直到用户通过以下任一方式关闭 pop-up选择确定或取消:
array=["a","b","c"];
array.sort(function(a,b){
var a_before_b = confirm("'" + a + "' will be sorted before '" + b
+ "'. Cancel to order differently.");
return a_before_b ? -1 : 1;
});
document.body.innerHTML = '<p>Array sorted: ' + array + '</p>';
<p>You will get 2 to 3 pop up dialogs to sort [a, b, c]</p>
要让用户通过正常交互而不是模式对话框回答问题,并且仍然使用标准 sort 方法,是一项更艰巨的任务。
一个想法是保留一个给出的答案列表,并在每次有新答案可用时重复排序,通过 sort 回调函数提供这些答案。
一旦出现尚未给出答案的比较,您将向用户展示该比较,并以任何顺序完成其余排序。排序后的数组将被忽略,直到您获得所有比较的所有答案为止。
代码比较长,主要是跟页面的交互:
var array = ['a', 'b', 'c'];
var answers = [];
var questionTemplate = "Order '#' before or after '#'?";
var answerTemplate = "The array is sorted. Result: #.";
function logMsg(msg) {
$($('#log')[0].insertRow(-1).insertCell(-1)).text(msg);
}
function answer(order) {
// keep track of answers
answers.push(order);
// show answers also in a log table
logMsg($('#question').text() + ' - ' + (order<0? 'Before' : 'After'));
askNext();
}
function askNext() {
var arrayCopy = array.slice(0); // take real copy
var questionNo = -1;
arrayCopy.sort(function(a,b){
questionNo++
if (questionNo < answers.length) {
// we already asked this, so use that answer
return answers[questionNo];
}
if (questionNo == answers.length) {
// put question to user:
$('#question').text(questionTemplate.replace('#', a).replace('#', b));
}
// don't care for now, just finish it. We need first to
// get an answer, and will then restart the sort.
return -1;
});
if (array.length == answers.length) {
// Array is now sorted according to answers:
// Hide question section
$('#questionDiv').hide();
// Show the result
logMsg(answerTemplate.replace('#', arrayCopy));
}
}
function reset() {
$('#array').text(array);
$('#questionDiv').show()
$('#log').html(''); // empty log table
answers = [];
askNext();
}
// Set up click handlers
$('#reset').click(reset);
$('#before').click(answer.bind(null, -1));
$('#after').click(answer.bind(null, 1));
reset();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>The array <span id="array"></span> will be sorted by asking you questions:</p>
<table id="log"></table>
<div id="questionDiv">
<p id="question" style="font-weight: bold"></p>
<button id="before">Before</button><button id="after">After</button>
</div>
<button id="reset">Restart</button>
我正在尝试为 Javascript array.sort
方法制作自定义比较回调函数。它应该 return 一个取决于用户输入的值。
调用该回调函数时,它应该等到用户单击按钮。根据单击的按钮,该函数将知道两个元素中哪个更大以及 return 相应的结果(1 或 -1)。
我知道等待用户输入的唯一方法是使用事件侦听器函数,但我不知道如何使它适应我必须传递给 array.sort()
方法的自定义函数。
这是我正在尝试的代码;我知道这段代码行不通:
var array=["a","b","c"];
array.sort(function(a,b){
var result;
$("#button1").click(function(){
result = 1;
});
$("#button2").click(function(){
result = -1;
});
return result;
}
我开始认为不可能将 array.sort
函数用于此目的。
有办法吗?
您可以通过使用 window.confirm 方法以丑陋的方式执行此操作,该方法的行为是等待您的代码的进一步执行,直到用户通过以下任一方式关闭 pop-up选择确定或取消:
array=["a","b","c"];
array.sort(function(a,b){
var a_before_b = confirm("'" + a + "' will be sorted before '" + b
+ "'. Cancel to order differently.");
return a_before_b ? -1 : 1;
});
document.body.innerHTML = '<p>Array sorted: ' + array + '</p>';
<p>You will get 2 to 3 pop up dialogs to sort [a, b, c]</p>
要让用户通过正常交互而不是模式对话框回答问题,并且仍然使用标准 sort 方法,是一项更艰巨的任务。
一个想法是保留一个给出的答案列表,并在每次有新答案可用时重复排序,通过 sort 回调函数提供这些答案。
一旦出现尚未给出答案的比较,您将向用户展示该比较,并以任何顺序完成其余排序。排序后的数组将被忽略,直到您获得所有比较的所有答案为止。
代码比较长,主要是跟页面的交互:
var array = ['a', 'b', 'c'];
var answers = [];
var questionTemplate = "Order '#' before or after '#'?";
var answerTemplate = "The array is sorted. Result: #.";
function logMsg(msg) {
$($('#log')[0].insertRow(-1).insertCell(-1)).text(msg);
}
function answer(order) {
// keep track of answers
answers.push(order);
// show answers also in a log table
logMsg($('#question').text() + ' - ' + (order<0? 'Before' : 'After'));
askNext();
}
function askNext() {
var arrayCopy = array.slice(0); // take real copy
var questionNo = -1;
arrayCopy.sort(function(a,b){
questionNo++
if (questionNo < answers.length) {
// we already asked this, so use that answer
return answers[questionNo];
}
if (questionNo == answers.length) {
// put question to user:
$('#question').text(questionTemplate.replace('#', a).replace('#', b));
}
// don't care for now, just finish it. We need first to
// get an answer, and will then restart the sort.
return -1;
});
if (array.length == answers.length) {
// Array is now sorted according to answers:
// Hide question section
$('#questionDiv').hide();
// Show the result
logMsg(answerTemplate.replace('#', arrayCopy));
}
}
function reset() {
$('#array').text(array);
$('#questionDiv').show()
$('#log').html(''); // empty log table
answers = [];
askNext();
}
// Set up click handlers
$('#reset').click(reset);
$('#before').click(answer.bind(null, -1));
$('#after').click(answer.bind(null, 1));
reset();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>The array <span id="array"></span> will be sorted by asking you questions:</p>
<table id="log"></table>
<div id="questionDiv">
<p id="question" style="font-weight: bold"></p>
<button id="before">Before</button><button id="after">After</button>
</div>
<button id="reset">Restart</button>