如何消除单个数组中元素的额外匹配
How to eliminate extra matches of element in single array
我试图返回数组的模式。我有一个内部循环和外部循环来比较每个元素。数组=[5,3,6,3,3,3]。
function mode(arr){
for (var i = 0; i < arr.length; i++) {
for (var k = i+1; k < arr.length; k++) {
if (arr[i] == arr[k]) {
modeItems += arr[k];
}else {
otherItems +=arr[i];
}
}
}return modeItems;
}
返回"333333"而不是"3333"。我看到这是如何发生在excel表格比较15个总循环aar[I]和arr[k],但我不知道该怎么做。
下面是一个大杂烩的答案。我的困惑源于标题
如何消除单个数组中元素的额外匹配
与问题的这一部分混在一起
我正在尝试返回数组的模式。
将数组简化为单个实例的数组和所有重复项的数组。
演示var arra = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4];
function simplify(arr) {
var c = {}, o = [], d = [], i;
for (i = 0; i < arr.length; i++) {
if (!c.hasOwnProperty(arr[i])) {
c[arr[i]] = arr[i];
o.push(arr[i]);
} else {
d.push(arr[i]);
}
}
return {
reduced: o,
duplicates: d
};
}
console.log(simplify(arra));
// >> [object Object] {
// >> duplicates: [2, 3, 3, 4, 4, 4],
// >> reduced: [1, 2, 3, 4]
// >> }
从数组中删除重复项。
演示var arr = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4];
function elim (arra) {
var c = {}, i = 0;
while (i < arra.length) {
if (c[arra[i]]) {
arra.splice(i, 1);
} else {
c[arra[i]] = true;
i++;
}
}
return arra; // only required for debug.
}
console.log(elim(arr.slice()));
在数组上循环这么多次只是为了找到模式是不必要的。您可以使用对象文字作为缓存来更新计数。如果你想要一个数组减去模式(或者一个数组只有模式),你可以在后面使用.filter
。
这是一个基本的实现。如果没有模式,则返回null。
演示function findMode (a) {
var cache = {},
len = a.length,
mode,
max = 0,
matched = false;
for (var i = 0; i < len; i++) {
cache[a[i]] = (cache[a[i]] + 1 || 1);
if (cache[a[i]] === max) {
matched = true;
} else if (cache[a[i]] > max) {
max = cache[a[i]];
mode = a[i];
matched = false;
}
}
return (matched ? null : mode);
}
var arr = [5,3,6,3,3,3],
myMode = findMode(arr),
filteredArr = arr.filter(function (e) {
return (e !== myMode);
}),
modeItems = arr.filter(function (e) {
return (e === myMode);
});
console.log(arr); // >> [5,3,6,3,3,3]
console.log(myMode); // >> 3
console.log(filteredArr); // >> [5, 6]
console.log(modeItems); // >> [3, 3, 3, 3]
这里没有模式:
findMode([5, 7, 5, 7]); // >> null
稍微复杂一点的东西。在原始数组的两次传递中返回模式、模式数组和逆数组。
演示var findMode = (function () {
function getMode (a) {
var cache = {},
len = a.length,
mode,
max = 0,
matched = false;
for (var i = 0; i < len; i++) {
cache[a[i]] = (cache[a[i]] + 1 || 1);
if (cache[a[i]] === max) {
matched = true;
} else if (cache[a[i]] > max) {
max = cache[a[i]];
mode = a[i];
matched = false;
}
}
return (matched ? null : mode);
}
function split (arr, mode) {
var set = [],
inverse = [];
if (mode !== null) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] === mode) {
set.push(arr[i]);
} else {
inverse.push(arr[i]);
}
}
}
return [set, inverse];
}
return (function (arr) {
var mode = getMode(arr),
lists = split(arr, mode);
return {
mode: mode,
set: lists[0],
inverse: lists[1]
};
});
}());
var info = findMode([5,3,6,3,3,3]),
noMode = findMode([5, 7, 5, 7]);
console.log(info);
console.log(noMode);
维护一个对象数组来保存处理过的项,忽略下一个迭代器中已经处理过的项。
function mode(arr) {
var processed = {};
for (var i = 0; i < arr.length; i++) {
for (var k = i + 1; k < arr.length; k++) {
if (arr[i] == arr[k]) {
modeItems += arr[k];
modeItems += !processed[arr[k]] ? arr[k] : '';
processed[arr[k]] = i;
break;
} else {
otherItems += arr[i];
}
}
}
return modeItems;
}
Output: 3,3,3,3
您的代码正在工作匹配,对于循环中的每个数字,索引i+1
之后的数字:
[5,3,6,3,3,3]
^ ^ //first match
[5,3,6,3,3,3]
^ ^ // match 2
[5,3,6,3,3,3]
^ ^ // match 3
[5,3,6,3,3,3]
^ ^ // match 4
[5,3,6,3,3,3]
^ ^ // match 5
[5,3,6,3,3,3]
^ ^ // match 6
解决这个问题的一个简单方法是,如果i
已经匹配,则重置continue
循环;但是如果你有多个双引号,它就会失败。
让我也加入我的观点。此代码删除匹配的项,不再使用:)
function mode(arr){
var key = arr[0], // it wil be the mode, current value of array
count = 1, // it will be the count of mode value
icount;
for (var i = 0; i < arr.length-count+1; i++) { // there is no need to look any further -
// count is more then rest items
if (!arr[i]) continue;
icount = 1;
for (var k = i+1; k < arr.length; k++) {
if (!arr[k]) continue;
if (arr[i] == arr[k]) { icount++; delete arr[k]; }
}
if (icount > count) { count = icount; key = arr[i]; }
}
if (count == 1) ret = null; // At this moment key - mode. Below output
else { var ret = []; while(count--) ret[count] = key; ret = ret.join();}
return ret;
}
相关文章:
- CKEditor Widget-阻止编辑可编辑元素本身
- 如何设置html元素填充的动画
- 如何将HTML id分配给元素,以及如何将JavaScript应用于元素
- 使用 jQuery 的 .on 函数如何获取事件的原始元素
- 使用clickToggle并在单击另一个元素时关闭元素
- 单击时将焦点更改为元素
- 表追加而不附加最后一个元素
- 如何在jQuery中获取元素的形式
- 我可以获得相对于被点击元素的确切点击位置吗
- 在函数中添加数组元素的数值
- 在单击任何位置时隐藏元素,而不检查每次DOM单击
- 将视口底部滚动到元素底部
- 是否有任何snippet或jQuery插件可以列出easylist.txt模式匹配的DOM中的所有元素
- 在不使用JQuery的情况下隐藏DOM中的选定元素
- 如何使用jquery处理php循环通过元素
- Ckeditor-plugin:插入虚假元素add不情愿<p>标签前后
- 消隐数组元素是否生成自己的属性
- Javascript获取元素背景图像,但消除了“;url()”;
- jQuery$.data()方法与直接将变量附加到DOM元素有何不同
- 在 JavaScript 中使用重排隐藏元素,它与 CSS 隐藏属性有何不同