Related
My array is:
const arr = [1, 4, 8, 10, 5, 7, 5, 9, 7, 5, 44, 6]
This is how you could go about sorting your array:
const arr = [1, 5, 7, 44, 5, 9, 4, 5, 9, 10, 6, 7, 8];
const uniqueArr = arr.filter(function(item, idx, self) {
return self.indexOf(item) == idx;
})
const sortedArr = uniqueArr.sort(function(a, b) {
return a - b;
});
console.log(sortedArr);
const arr = [1, 4, 8, 10, 5, 7, 5, 9, 7, 5, 44, 6];
arr.sort((a,b) => {return a - b;});
let len = arr.length;
const unique = [];
for(let i = 0; i < len; i++){
if(unique.indexOf(arr[i]) === -1){
unique.push(arr[i]);
}
}
console.log(unique);
info before: i have halfway succeded, as i managed to print out it and it didnt loop crazy, however i did not manage to find the reason why it still prints out a undefinded
HTML: <button id="btn">button</button>
<label id="textarea"></label>
var tall = [4, 5, 2, 3, 4, 6, 1, 2, 0, 9, 7, 6, 8, 5, 6, 4, 2, 3, 5]
var btn = document.getElementById("btn");
tall.sort(function(a, b){return a-b})
btn.onclick = function(){
for( var i = 0; i < tall.length; i++){
a = 0;
for(var j = 0; j<i ; j++){
a++;
tall.splice(i, 2)
document.write("number "+tall[i]+" is "+ a+" times<br>")
}
}
}
we can use reduce to calculate how many times number is shown
then we can use Object.entries with forEach - to show data to UI
var tall = [4, 5, 2, 3, 4, 6, 1, 2, 0, 9, 7, 6, 8, 5, 6, 4, 2, 3, 5]
var btn = document.getElementById("btn");
btn.onclick = function(){
const objectResult = tall.reduce((a,c) => (a.hasOwnProperty(c) ? {...a, [c]: a[c] + 1} : {...a, [c]: 1}), {});
Object.entries(objectResult).forEach(([number, times]) => document.write(`number: ${number} is ${times} times<br>`))
}
<button id="btn">button</button>
<label id="textarea"></label>
Using the reduce function, you can iterate over your array and generate an output based on action you perform on each next Value in the Array.
We start with an empty object, if we find that the nextValue is not yet stored we store it in that object with value 1, if we see that the nextValue already exists, we increment the count in the result.
const data = [4, 5, 2, 3, 4, 6, 1, 2, 0, 9, 7, 6, 8, 5, 6, 4, 2, 3, 5]
const result = data.reduce((result, nextValue) => {
if (nextValue in result)
result[nextValue]++
else
result[nextValue] = 1
return result
}, {}) // initial result is an empty object set with ', {}'
console.log(result)
var tall = [4, 5, 2, 3, 4, 6, 1, 2, 0, 9, 7, 6, 8, 5, 6, 4, 2, 3, 5];
var map = tall.reduce(function(prev, cur) {
prev[cur] = (prev[cur] || 0) + 1;
return prev;
}, {});
console.log(map)
Here you go:
const list = document.querySelector('ul')
const button = document.querySelector('button')
const tall = [4, 5, 2, 3, 4, 6, 1, 2, 0, 9, 7, 6, 8, 5, 6, 4, 2, 3, 5]
// Cals result
const result = tall.reduce((res, value) => {
if (value in res)
res[value]++
else
res[value] = 1
return res
}, {})
button.addEventListener('click', () => {
list.innerHTML = ''
// Add li element for each result
Object.keys(result).forEach(res => {
const li = document.createElement('li')
li.textContent = `${res} occures ${result[res]} times`
list.append(li)
})
})
<button>Write data to list</button>
<ul>
<ul>
This will give you the occurrences of each number in an object.
I have an array of object, which every object contain a section and a data;
const arr = [
{ section: "a", data: [1, 2] },
{ section: "b", data: [3, 4, 5, 6] },
{ section: "c", data: [7, 8, 9, 10, 11, 12, 13] }
];
Now I want to paginate it.
I need to display 4 item in one page.
So it would be like:
[
{page: 1, section: ['a', 'b'], data: [1, 2, 3, 4]}
{page: 2, section: ['b', 'c'], data: [5, 6, 7, 8]}
{page: 3, section: ['c'], data: [9, 10, 11, 12]}
{page: 4, section: ['c'], data: [13]}
]
Any help, I tried many ways but still could not solve.
My Efforts
const arr = [
{ title: "a", data: [1, 2] },
{ title: "b", data: [3, 4, 5, 6] },
{ title: "c", data: [7, 8, 9, 10, 11, 12, 13] }
];
let c = 0, na = [], ha = [];
for(let i = 0; i < arr.length; i++){
let ia = arr[i].data;
for(let k = 0; k < ia.length; k++){
na = [...na, [ arr[i].title, ia[k] ]];
// na = [...na, {[c]: {section: arr[i].title, data: ia[k]}}]; c++;
}
}
// console.log(JSON.stringify(na));
function chunk (arr, len) {
var chunks = [], i = 0, n = arr.length;
while (i < n) {
chunks.push(arr.slice(i, i += len));
}
return chunks;
}
const resCh = chunk(na, 3);
console.log(resCh);
let finalArr = [];
for(let i = 0; i< resCh.length; i++){
let nstd = resCh[i], finalObj = {};
nstd.reduce( (t, s) => {
if(t[0] === s[0]) {
if(finalObj[t[0]]){
finalObj = {
...finalObj,
[t[0]]: [
...finalObj[t[0]],
t[1], s[1]
]
}
}else {
finalObj = {
...finalObj,
[t[0]]: [t[1], s[1]]
}
}
}else {
if(finalObj[t[0]]){
finalObj = {
...finalObj,
[t[0]]: [
...finalObj[t[0]],
t[1]
]
}
}else {
finalObj = {
...finalObj,
[t[0]]: [ t[1] ]
}
}
}
return s;
});
finalArr.push(finalObj);
}
console.log(finalArr);
You could do something like this:
const arr = [
{ section: "a", data: [1, 2] },
{ section: "b", data: [3, 4, 5, 6] },
{ section: "c", data: [7, 8, 9, 10, 11, 12, 13] }
];
const fillRange = (start, end) => {
return Array(end - start + 1).fill().map((item, index) => start + index);
};
let result = [];
let j = 0
let maxData = Math.max(...arr.map(x => x.data).flat(2))
for (let i = 0; i < 4; i++) {
if (j === 0) j = i + 1;
else j = j + 4;
const finalData = fillRange(j, j + 3).filter(x => x <= maxData);
let section = [];
arr.forEach(val => {
if(val.data.some(v => finalData.includes(v))) section.push(val.section);
});
let resObj = {page: i + 1, section: section, data: finalData}
result.push(resObj)
}
console.log(result)
Explanation:
With fillRange function I create arrays of consecutive numbers 4 by 4 (like [1,2,3,4][5,6,7,8]...). These values have an upper bound = max value found in all data arrays (fillRange(j, j + 3).filter(x => x <= maxData));
Find the section for which data includes these numbers;
Crete result object with all data found before and push it in result array.
What I'm trying to do is find how many times an array elements repeats itself in array, push the element along with the number of repeats it has in an object and after that delete the element and all its duplicates.
At the moment I have this function :
function getDuplicates(arr) {
let lastIndex = null;
let obj = {};
for ( let i = 0; i < arr.length; i++ ) {
lastIndex = arr.lastIndexOf(arr[i]);
obj[arr[i]] = lastIndex + 1;
arr.splice(0, lastIndex + 1 );
}
console.log(obj);
}
getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);
which logs : { '1': 4, '2': 2, '3': 4, '5': 5 }
It works great for the first 3 numbers ( 1,2 and 3 ) but 4 doesnt show up, 5 is messed up and 6 doesnt show due to lastIndex +1. Am I missing something or is there a better way to do this ?
Thank you.
You can simplify a lot the logic. Just an object to count and an if statement to increment values or define as 1 if it wasn't defined.
function countDuplicates(arr) {
// Contains a pair of values an instances.
var counting = {};
// Iterate array: check if already counted. If yes, increment, if not define as 1.
for (el of arr) (counting[el]) ? counting[el]++ : counting[el] = 1;
console.log(counting);
return counting;
}
countDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);
Adding, if you also want to get the unique elements, you can just use E6 set:
var set = new Set([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);
You can count and print as you would want like this:
function getDuplicates(arr) {
var counts = {};
arr.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
console.log(counts);
}
function getDuplicates(arr) {
let lastNum = null;
let obj = {};
for ( let i = 0; i < arr.length; i++ ) {
if (arr[i] != lastNum){
lastNum = arr[i];
obj[arr[i]] = 1;
}else{
obj[arr[i]]++;
}
}
console.log(obj);
}
You can simply use Array#reduce() to count the occurrences and Array#filter() to remove the duplicates
getDuplicates([1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6]);
function getDuplicates(arr) {
var obj = arr.reduce((map, item) => (map[item] = ++map[item] || 1, map),{} );
var withoutDup = arr.filter((item, pos) => arr.indexOf(item) == pos);
console.log(JSON.stringify(obj));
console.log(JSON.stringify(withoutDup));
}
Here's one method how to solve it.
Firstly I've removed all duplicated elements from the given array, using new Set() and then iterated over it using Array#forEach and checked with Array#filter how many times given element appears in the passed array.
function getDuplicates(arr){
var filtered = [...new Set(arr)],
result = {};
filtered.forEach(function(v){
result[v] = arr.filter(c => c == v).length;
})
console.log(result);
}
getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]);
Array#reduce solution.
function getDuplicates(arr) {
var res = arr.reduce(function(s, a) {
s[a] = arr.filter(c => c == a).length;
return s;
}, {});
console.log(res);
}
getDuplicates([1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6]);
It looks as if you want to COUNT duplicates, but if all you want to do is remove duplicates (As headline states), as per #ChantryCargill s suggestion:
function removeDuplicates (arr) {
var results = [];
for(var i = 0; i < arr.length; i++) {
var item = arr[i];
if(results.indexOf(item) === -1) {
results.push(item);
}
}
return results;
}
console.log(removeDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]));
//[1, 2, 3, 4, 5, 6]
If you want to COUNT duplicates:
function getDuplicates(arr) {
var results = {};
for(var item of arr) {
if(!results[item]) {
results[item] = 0;
}
results[item]++;
}
return results;
}
console.log(getDuplicates([ 1, 1, 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5, 6 ]));
//{"1":4,"2":2,"3":4,"4":2,"5":3,"6":1}
Try this:
function getDuplicates(){
var numbers=Array.prototype.slice.call(arguments);
var duplicates={};
for(var index in numbers){
if(numbers.indexOf(numbers[index])==index)
continue;
duplicates[numbers[index]]= (duplicates[numbers[index]] || 0) + 1;
}
return duplicates;
}
console.log(getDuplicates(1,2,3,1,1,3,4,5,6,7,8,6));
/*
prints {
1: 2,
3: 1,
6: 1
}
*/
What is the cleanest way to reduce those array ?
data = {
id: [1, 1, 1, 3, 3, 4, 5, 5, 5, ...]
v: [10,10,10, 5, 10 ...]
}
For each id there is a v corresponding. What I want is sum up v for each id. In this example the result should be
data = {
id: [1, 3, 4, 5, ...]
v: [30, 15, ...]
}
I would go for the Array.prototype.reduce() ,simple and elegant solution
var ids = [1, 1, 1, 3, 3, 3, 3, 4, 5, 6, 6, 6],
v = [10, 10, 10, 5, 10, 10, 10, 404, 505, 600, 60, 6],
data = {};
data.v = [];
data.ids = ids.reduce(function(a, b, index) {
if (a.indexOf(b) < 0) a.push(b);
if (!data.v[a.indexOf(b)]) data.v[a.indexOf(b)] = 0;
data.v[a.indexOf(b)] += v[index];
return a;
}, []);
https://jsfiddle.net/2ssbngLr/
One way of doing this, given two arrays of equal length would be to map/reduce them:
const ids = [1, 1, 1, 3, 3];
const vs = [10,10,10,5,10];
const reduced = ids
.map((val, i) => ({ id: val, value: vs[i] }))
.reduce((agg, next) => {
agg[next.id] = (agg[next.id] || 0) + next.value;
return agg;
}, {});
console.log(reduced);
// Object {1: 30, 3: 15}
Working example: https://jsfiddle.net/h1o5rker/1/
I think it can be accomplished with reduce
var data = {
id: [1, 1, 1, 3, 3],
v: [10, 10, 10, 5, 10]
}
var sumsObjs = data.v.reduce(function(sum, val, index) {
var id = data.id[index];
if (sum[id] !== undefined) {
sum[id] = sum[id] + val;
} else {
sum[id] = val;
}
return sum;
}, {});
console.log(sumsObjs);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>
var data={
id: [1,1,1,10,123,4531],
v:[123,123,53,223,11,11,11]
},
_v = data.v, vinit;
document.write(data.v+'<br>');
for(var i=0;i<_v.length;i++){
vinit = _v[i];
for(var j=i+1; j<=_v.length;j++){
if(_v[j]===vinit){
delete _v[j];
}
}
};
document.write(data.v);
var data={
id: [1,1,1,10,123,4531],
v:[123,123,53,223,11,11,11,...]
},
_v = data.v, vinit;
for(var i=0;i<_v.length;i++){
vinit = _v[i];
for(var j=i+1; j<=_v.length;j++){
if(_v[j]===vinit){
delete _v[j];
}
}
}
the above code is just for the v but you can simultaneously reduce the repeating elements for id too by introducing some more variables
in the snippet you can see that there are the extra commas in the second line which shows that those elements were deleted
If the ids are always in order, a simple for loop can solve it. There is no need to get overly complicated.
data = {
id: [1, 1, 1, 3, 3, 4, 5, 5, 5],
v: [10, 10, 10, 5, 10, 1, 2, 3, 4]
};
var result = {
id: [],
v: []
};
(function() {
var ids = data.id,
vals = data.v,
lastId = ids[0],
runningTotal = vals[0];
for (var i = 1; i < ids.length; i++) {
if (lastId === ids[i]) {
runningTotal += vals[i];
}
if (lastId !== ids[i] || i + 1 === ids.length) {
result.id.push(lastId);
result.v.push(runningTotal);
lastId = ids[i];
runningTotal = vals[i];
}
}
}());
console.log(result);
Some people have posted some good solutions so far, but I haven't really seen one that does exactly what you're looking for. Here is one that takes your specific object and returns an object of the same format, but meeting your requirements and reduced.
// Your data object
data = {
id: [1, 1, 1, 3, 3],
v: [10,10,10, 5, 10]
}
// Assuming obj consists of `id` and `v`
function reduce(obj){
// We create our reduced object
var reducedObj = {
id: [],
v: []
}
// Next we create a hash map to store keys and values
var map = {};
for(var i=0; i<obj.id.length; ++i){
// If this key doesn't exist, create it and give it a value
if(typeof map[parseInt(obj.id[i])] === 'undefined'){
map[parseInt(obj.id[i])] = 0;
}
// Sum all of the values together for each key
map[parseInt(obj.id[i])] += parseInt(obj.v[i]);
}
// Now we map back our hashmap to our reduced object
for(var ele in map){
reducedObj.id.push(ele);
reducedObj.v.push(map[ele]);
}
// Return our new reduced object
return reducedObj;
}
var myReducedObject = reduce(data);
console.log(myReducedObject);
Working Fiddle
This is a solution for ordered id with Array.prototype.reduce().
var data = {
id: [1, 1, 1, 3, 3, 4, 5, 5, 5],
v: [10, 10, 10, 5, 10, 7, 8, 10, 13]
},
result = { id: [], v: [] };
data.id.reduce(function (r, a, i) {
if (r === a) {
result.v[result.v.length - 1] += data.v[i];
} else {
result.id.push(a);
result.v.push(data.v[i]);
}
return a;
}, -1);
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');
Or a in situ version
var data = {
id: [1, 1, 1, 3, 3, 4, 5, 5, 5],
v: [10, 10, 10, 5, 10, 7, 8, 10, 13]
};
void function (d) {
var i = 1;
while (i < d.id.length) {
if (d.id[i - 1] === d.id[i]) {
d.id.splice(i, 1);
d.v[i - 1] += d.v.splice(i, 1)[0];
continue;
}
i++;
}
}(data);
document.write('<pre>' + JSON.stringify(data, 0, 4) + '</pre>');