我正在尝试获取数组中计数为偶数的元素,我具有以下代码。 说我检查这个数组:
function checkEither(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
var count = 0;
for (var j = 0; j < arr.length; j++) {
if (arr[j] == arr[i]) {
count++;
}
}
if ((count >= 3) || (count % 2 == 0)) {
newArr.push(arr[i]);
}
}
return newArr;
}
console.log(checkEither([10, 11, 12, 11, 10, 10, 13, 11, 12, 10, 13, 14, 11, 10, 12]));
我明白了
[ 10, 11, 12, 11, 10, 10, 13, 11, 12, 10, 13, 11, 10, 12 ]
代替
[ 10, 11, 12, 11, 10, 10, 13, 11, 12, 10, 13, 11 ]
该数组仍应包含出现奇数项的项目,但结果应显示该项目的偶数
10
出现五次,并且在新数组中应该只有四次。我该怎么办?谢谢
答案 0 :(得分:2)
这是问题所在:
if ((count >= 3) || (count % 2 == 0)) {
也就是说,如果条目的计数大于或等于3 或个计数为偶数,则包括该条目。因此,如果计数为5,则它匹配第一个条件并包含在内。
如果只想计数,请删除第一个条件:
if (count % 2 == 0) {
因为其中有5次出现,所以不会出现10个结果。
实时示例:
function checkEither(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
var count = 0;
for (var j = 0; j < arr.length; j++) {
if (arr[j] == arr[i]) {
count++;
}
}
if (count % 2 == 0) {
newArr.push(arr[i]);
}
}
return newArr;
}
console.log(checkEither([10, 11, 12, 11, 10, 10, 13, 11, 12, 10, 13, 14, 11, 10, 12]));
如果您还希望结果仅一次而不是重复包含每个数字,则需要检查结果数组中是否已经包含该数字,请参见***
行:
function checkEither(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (!newArr.includes(arr[i])) { // ***
var count = 0;
for (var j = 0; j < arr.length; j++) {
if (arr[j] == arr[i]) {
count++;
}
}
if (count % 2 == 0) {
newArr.push(arr[i]);
}
}
}
return newArr;
}
console.log(checkEither([10, 11, 12, 11, 10, 10, 13, 11, 12, 10, 13, 14, 11, 10, 12]));
这涉及到每次重新扫描newArr
,这对于小型阵列(例如所讨论的阵列,甚至中等大小的阵列)来说绝对合适。对于非常大的数组,您可能希望跟踪Set
(或对象(如果必须支持过时的平台,则为对象)中的已知数字),因为使用Set
的查找时间比线性查找时间要好:
function checkEither(arr) {
var checked = new Set(); // ***
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (!checked.has(arr[i])) { // ***
var count = 0;
for (var j = 0; j < arr.length; j++) {
if (arr[j] == arr[i]) {
count++;
}
}
if (count % 2 == 0) {
newArr.push(arr[i]);
checked.add(arr[i]); // ***
}
}
}
return newArr;
}
console.log(checkEither([10, 11, 12, 11, 10, 10, 13, 11, 12, 10, 13, 14, 11, 10, 12]));
答案 1 :(得分:1)
您可以使用Array.prototype.filter
两次来完成所需的操作。
在内部filter
函数(checkItem
)中,您需要找到一个项目在数组中存在的次数,并获取最后一个索引。
外部filter
函数(checkEither
)中的int如果计数可以被2整除并且该项目不是其类型的最后一个项目,则返回true。
function checkEither(arr) {
return arr.filter(function(item, index) {
var { lastIndex, result } = checkItem(arr, item);
return (result % 2 === 0) || (lastIndex !== index);
});
}
function checkItem(arr, item) {
var lastIndex = 0;
var result = arr.filter(function(val, index) {
var areEqual = val === item;
if (areEqual) lastIndex = index;
return areEqual;
}).length;
return { lastIndex, result };
}
console.log(checkEither([10, 11, 12, 11, 10, 10, 13, 11, 12, 10, 13, 14, 11, 10, 12]));
console.log(checkEither([1, 1, 2, 3, 3, 3]));
为提高效率,您可以缓存每个项目的结果,以避免多次检查同一项目。
function checkEither(arr) {
var results = {};
return arr.filter(function(item, index) {
results[item] = results[item] || checkItem(arr, item);
var { lastIndex, result } = results[item];
return (result % 2 === 0) || (lastIndex !== index);
});
}
function checkItem(arr, item) {
var lastIndex = 0;
var result = arr.filter(function(val, index) {
var areEqual = val === item;
if (areEqual) lastIndex = index;
return areEqual;
}).length;
return { lastIndex, result };
}
console.log(checkEither([10, 11, 12, 11, 10, 10, 13, 11, 12, 10, 13, 14, 11, 10, 12]));
console.log(checkEither([1, 1, 2, 3, 3, 3]));
答案 2 :(得分:0)
您可以获取计数,将值调整为偶数,然后通过减少计数进行过滤。
module.exports = function (env) {
env = env || {};
var isProd = env.NODE_ENV === 'production';
// Setup base config for all environments
var config = {
context: path.resolve(__dirname, "Features"),
entry: {
"Maps": [ "./Map/Scripts/map.js"],
},
output: {
path: path.join(__dirname, 'wwwroot/dist'),
filename: '[name].js'
},
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
},
module: {
rules: [
{ test: /\.css?$/, use: ['style-loader', 'css-loader'] },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' },
{ test: /\.(png|woff|woff2|eot|ttf|svg)(\?|$)/, use: 'url-loader?limit=100000' },
{ test: /\.tsx?$/, use: "ts-loader", exclude: /node_modules/ }
]
}
}
return config;
使用对象和触发器将值从function checkEither(array) {
var count = array.reduce((c, v) => (c[v] = (c[v] || 0) + 1, c), {});
Object.keys(count).forEach(k => count[k] = count[k] >> 1 << 1);
return array.filter(v => count[v] && count[v]--);
}
console.log(checkEither([10, 11, 12, 11, 10, 10, 13, 11, 12, 10, 13, 14, 11, 10, 12]).join(' '));
更改为实际索引(对于不均匀计数),反之亦然,对于偶数计数,只有两个循环的解决方案。
例如使用
undefined
10
结果是过滤后的不包含元素的数组,这些元素具有存储的值索引。
index indices[10] comment
----- ----------- ------------------------------------
undefined at start
0 0
4 undefined
5 5
9 undefined
13 13 at this index, the value is filtered
答案 3 :(得分:0)
仅需注意,此解决方案具有O(n ^ 2),对于更大的数据集将是可怕的。取决于输入集(如果所有输入都是体面范围内的整数),则可以在数字和辅助数组索引之间进行投影,其中index表示第一个数组中数字的值。然后,在该索引上,每当在第一个数组中找到该值时,就增加1。最后,您从头到尾读取了该数组(辅助对象1),并在其中列出了每个偶数的索引。
在该解决方案中,您拥有O(2n),即O(n),自己计算一组仅10k大数组的时间差;)
您可以在这里找到带有图片的方法,而不是更详细;)
indexing array values in another array
请注意,您也可以使用十进制数字数组(乘以10 ^ n并得到所有整数),负数(从最左边的1移到0并在此处开始索引)进行此操作。
对我来说,任何非初级程序员都不会接受将线性时间(和一个简单的实现)上的二次时间复杂度作为可行的解决方案,除非已知数据集很小且永远不会增长。