所以我一直在研究这项任务已经有一段时间了,我遇到了问题。我一遍又一遍地尝试和重写,似乎无法为此提出足够好的解决方案。
我正在尝试将一个对象数组排序到另一个对象数组中。我正在使用淘汰赛,但如果可以在vanilla JS或jQuery中更直接地完成,那么解决方案不必包含knockout。
我将解释:
我们从observableArray serials
开始,其中包含一些序列号对象。此数组始终包含以下格式:
var serials = ko.observableArray([
{ number: "DFG09008", qty: 1 },
{ number: "DFG09009", qty: 1 },
{ number: "DFG09010", qty: 1 },
{ number: "DFG09011", qty: 1 },
{ number: "DFG09020", qty: 1 },
{ number: "ASD-0001", qty: 1 },
{ number: "ASD-0002", qty: 1 },
{ number: "HJ-DRT-06", qty: 1 },
{ number: "HJ-DRT-07", qty: 1 },
{ number: "POU055054", qty: 1 }
]);
// qty property is for something unrelated to this in the app
我写的函数的期望结果是它将输出到另一个observableArray displaySerials
,用于表示“数值范围”的概念:
var displaySerials = ko.observableArray([
{ beginSerial: "DFG09008", endSerial: "DFG09011" },
{ beginSerial: "DFG09020", endSerial: "" },
{ beginSerial: "ASD-0001", endSerial: "ASD-0002" },
{ beginSerial: "HJ-DRT-06", endSerial: "HJ-DRT-07" },
{ beginSerial: "POU055054", endSerial: "" }
]);
所以,因为serials
'前四名成员' number
属性"DFG09008", "DFG09009", "DFG09010", "DFG09011"
具有匹配的前缀(DFG090
)和后缀数字(8, 9, 10, 11
),它们被放入beginSerial
所在的对象中范围中的最小数字(DFG09008
)和endSerial
最高(DFG09011
)。请注意,"DFG09020"
放在一个单独的对象中。这是因为它与组中的其他数字不连续,因此它本身被考虑。
任何与该组其余部分无关的序列号都会放入其自己的对象中,其中endSerial
属性为空字符串:{ beginSerial: "DFG09020", endSerial: "" }
序列号结构化方式的唯一定义规则是它们将始终以数字结尾。但是收藏中可能有数十或数百个。
只有有效解决方案的要求是上面提到的以及:
serials
应保持不变。非常感谢任何贡献!
答案 0 :(得分:0)
看起来你不需要排序它们就像 group 它们一样。他们似乎已经井井有条。您需要做的就是浏览列表,看看每个列表是否与前一个序列相同。如果是,那就是你正在建造的displaySerial的结尾;如果没有,你开始一个新的displaySerial。
也许棘手的部分是确定它们是否是顺序的。我选择使用正则表达式来分割尾随数字。如果非数字部分相等且数字不同,则为顺序。
此处不需要Knockout或jQuery。你没有对DOM做任何事情。您可以使用实用程序功能,但没有太多理由。我只是用Knockout来显示结果。
如果你做需要对它们进行排序,你可以使用比较函数和相同的正则表达式分割器,首先比较非数字部分,如果非数字部分相等则数字。< / p>
// test data
var serials = [
{ number: "DFG09008", qty: 1 },
{ number: "DFG09009", qty: 1 },
{ number: "DFG09010", qty: 1 },
{ number: "DFG09011", qty: 1 },
{ number: "DFG09020", qty: 1 },
{ number: "ASD-0001", qty: 1 },
{ number: "ASD-0002", qty: 1 },
{ number: "HJ-DRT-06", qty: 1 },
{ number: "HJ-DRT-07", qty: 1 },
{ number: "POU055054", qty: 1 }
];
// constructor for displaySerials array
function DisplaySerial (beginSerial, endSerial) {
this.beginSerial = beginSerial;
this.endSerial = endSerial;
}
var serialPartsPattern = /(.*\D)(\d+)$/;
function isSequential(s1, s2) {
if (s1 === undefined) return false;
var m1 = s1.match(serialPartsPattern),
m2 = s2.match(serialPartsPattern);
return m1[1] === m2[1] && (+m1[2] + 1) === +m2[2];
}
var displaySerials = [],
currentSerial,
prevSerial,
currentDisplaySerial;
for (var i=0; i<serials.length; ++i) {
currentSerial = serials[i].number;
if (isSequential(prevSerial, currentSerial)) {
currentDisplaySerial.endSerial = currentSerial;
}
else {
currentDisplaySerial = new DisplaySerial(currentSerial, "");
displaySerials.push(currentDisplaySerial);
}
prevSerial = currentSerial;
}
ko.applyBindings({displaySerials: displaySerials});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ol data-bind="foreach:displaySerials">
<li><span data-bind="text:beginSerial"></span>...<span data-bind="text:endSerial"></span></li>
</ol>
&#13;
答案 1 :(得分:0)
我正在附加基于lodash的解决方案。我假设你的价值不一定要排序。请注意,我添加了更多值以正确显示其排序和分组,并且我更改了顺序。
<script src="https://cdn.rawgit.com/lodash/lodash/3.0.1/lodash.min.js"></script>
var data = require('./path/to/index')