Всем привет! Имеется массив
var arr=["aa","aa","ab","ab","ac","a","s",];
var arr = ["aa", "aa", "ab", "ab", "ac", "a", "s", ];
var arr2 = [];
for (i in arr) {
if (arr2[arr[i]] != undefined) {
(arr2[arr[i]] ++)
} else {
(arr2[arr[i]] = 1)
}
}
console.log(arr2);
Функция sort может принимать функцию сравнения, в которой как раз и можно сравнивать количество повторений, а не зами элементы.
Кроме того, так как в массив добавляются нечисловые ключи, можно обойтись без второго массива:
for (var len = arr.length, i = len; --i >= 0;) {
if (arr[arr[i]]) {
arr[arr[i]] += 1;
arr.splice(i, 1);
} else {
arr[arr[i]] = 1;
}
}
Так как добавленные свойства не числовые, они не участвуют в сортировке, но к ним можно обращаться в функции сравнения:
arr.sort(function(a, b) {
return arr[b] - arr[a];
});
Для вывода можно воспользоваться несколькими путями: например, получить новый массив с элементами в которых будут поля соответствующие и элементу, и количеству его повторений. Либо воспользоваться функцией JSON.stringify
Пример:
var arr = ["aa", "aa", "ab", "ab", "ac", "a", "s"];
for (var len = arr.length, i = len; --i >= 0;) {
if (arr[arr[i]]) {
arr[arr[i]] += 1;
arr.splice(i, 1);
} else {
arr[arr[i]] = 1;
}
}
arr.sort(function(a, b) {
return arr[b] - arr[a];
});
console.log(arr);
var stringResult = JSON.stringify(arr, function(k, v) {
if (k == '') return v;
return `${v} - ${arr[v]}`;
}, 2);
document.getElementById('result').innerHTML = stringResult;
console.log(stringResult);
console.log(arr.map((el, i, a) => ({
[el]: a[el]
})));
<pre id="result"></pre>
Чтобы не работать с массивом как с объектами можно воспользоваться функцией reduce и сразу получить массив, который можно будет отсортировать.
var arr = ["aa", "aa", "ab", "ab", "ac", "a", "s", "s", "s"];
var resultReduce = arr.reduce(function(acc, cur) {
if (!acc.hash[cur]) {
acc.hash[cur] = { [cur]: 1 };
acc.map.set(acc.hash[cur], 1);
acc.result.push(acc.hash[cur]);
} else {
acc.hash[cur][cur] += 1;
acc.map.set(acc.hash[cur], acc.hash[cur][cur]);
}
return acc;
}, {
hash: {},
map: new Map(),
result: []
});
var result = resultReduce.result.sort(function(a, b) {
return resultReduce.map.get(b) - resultReduce.map.get(a);
});
console.log(result);
вот вам два решения - второе использует es6
структуру Map
, первое довольно банальное.
А для сортировки нужно получить массив, например вот такого вида
[{arrayItem: aa, count: 2}, {arrayItem: ab, count: 2}, ...]
чтобы была возможность отсортировать эти элементы по полю count
, а индексы должны быть целочисленными, у вас они строковые, потому и не отсортировать их.
var arr = ["aa", "aa", "ab", "ab", "ac", "a", "s", "s", "s"];
function getCountsSorted_1(arr) {
var counts = [];
var res = [];
for (var i in arr) {
if (counts[arr[i]]) {
(counts[arr[i]]++);
} else {
(counts[arr[i]] = 1)
}
}
var j = 0;
for (var i in counts) {
res[j++] = {
arrayItem: i,
count: counts[i]
};
}
return res.sort(function(a, b) {
return a.count < b.count;
}).map(function(entry) {
var ret = {};
ret[entry.arrayItem] = entry.count;
return ret;
});
}
function getCountsSorted_2(arr) {
var counts = new Map();
for (var i in arr) {
if (counts.has(arr[i])) {
counts.set(arr[i], counts.get(arr[i]) + 1);
} else {
counts.set(arr[i], 1);
}
}
return Array.from(counts).sort(function(a, b) {
return a[1] < b[1];
}).map(function(entry) {
var ret = {};
ret[entry[0]] = entry[1];
return ret;
});
}
console.log(getCountsSorted_1(arr));
console.log(getCountsSorted_2(arr));
var arr = ["aa", "aa", "ab", "ab", "ab", "ac", "a", "s", ];
var arr2 = {};
var arr3 = {};
for (var i = 0; i < arr.length; i++) {
if (arr2[arr[i]]) {
arr2[arr[i]] += 1;
} else {
arr2[arr[i]] = 1;
}
}
console.log(arr2);
var forsort = [];
for (var item in arr2)
forsort.push([item, arr2[item]])
forsort.sort(
function(a, b) {
return b[1] - a[1]
})
for (var z = 0; z < forsort.length; z++) {
arr3[forsort[z][0]] = forsort[z][1];
}
console.log(arr3);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="arr1"></span>
В итоге рабочий код:
var arr = ["aa", "aa", "ab", "ab", "ac", "a", "s", "s", "s"];
var resultReduce = arr.reduce(function(acc, cur) {
if (!acc.hash[cur]) {
acc.hash[cur] = { [cur]: 1 };
acc.map.set(acc.hash[cur], 1);
acc.result.push(acc.hash[cur]);
} else {
acc.hash[cur][cur] += 1;
acc.map.set(acc.hash[cur], acc.hash[cur][cur]);
}
return acc;
}, {
hash: {},
map: new Map(),
result: []
});
var result = resultReduce.result.sort(function(a, b) {
return resultReduce.map.get(b) - resultReduce.map.get(a);
});
console.log(result);
Но теперь надо, чтобы результат выводился в любое место на экран с указанием количества повторов. У меня получается выводить только сами значений массива, кол-во почему-то не выводится?
var arr = ["aa", "aa", "ab", "ab", "ac", "a", "s"],
counts = {},
res = [];
for (var i in arr) {
counts[arr[i]] = (counts[arr[i]] || 0) + 1;
}
Object.keys(counts).sort(function(a, b) {
return counts[b] - counts[a]
}).forEach(function(el, idx, arr) {
res.push([el, counts[el]]);
});
console.log(res);
Виртуальный выделенный сервер (VDS) становится отличным выбором
Хочу по нажатию на ссылку на одной странице, изменить элемент другой страницы(изменить тэг) и что-бы это было real time, подскажите как можно это...
Как сделать, чтобы при нажатии на кнопку появлялся еще один такой блок
Есть 3 секции : <div id="welcome">