Split array into sub arrays and replace character - javascript

I need to split an array into several sub arrays and replace a certain character.
First I run a function to count the number of duplicates in the array. Then I build a new array with the values and the number of instances of the value.
Code:
angular.forEach($scope.financial, function(data) {
counts[data] = (counts[data] || 0)+1;
})
Result:
[4, {25: 4}, 5, {25: 1}, 3, {10: 1}, 4, {10: 1}]
What I am looking for is to split the array into several sub arrays and replace the colon with a comma.
Like this:
[[4,25,4],[5,25,1],[3,10,1],[4,10,1]]
Any suggestions?

That can be done with a simple loop. But, some checks for the integrity of the data would be advised if you can't guarantee the format of the input.
function getKey(o) {
for (var prop in o) {
if (o.hasOwnProperty(prop)) {
return prop;
}
}
}
var data = [4, {25: 4}, 5, {25: 1}, 3, {10: 1}, 4, {10: 1}];
var i = 0;
var output = [];
var key;
for (i = 0; i < data.length; i += 2) {
key = getKey(data[i + 1]);
output.push([data[i], parseInt(key, 10), data[i + 1][key]]);
}
//Print the output
console.log(output);
var el = document.createElement('div');
el.innerHTML = JSON.stringify(output);
document.body.appendChild(el);

The below mentioned converter function will accept the reponseArray of type [4, {25: 4}, 5, {25: 1}, 3, {10: 1}, 4, {10: 1}] and converts into subarray [[4,25,4],[5,25,1],[3,10,1],[4,10,1]]
fiddle
function converter(responseArray) {
var mainArray=[], subArray;
for (var i = 0; i < responseArray.length; i++) {
if(i%2 == 0) {
subArray= [];
subArray.push(responseArray[i]);
} else {
var obj = responseArray[i];
for(var key in obj) {
subArray.push(key * 1);
subArray.push(obj[key] * 1);
}
mainArray.push(subArray);
}
}
console.log(mainArray);
return mainArray;
}

Related

Get 1 element from each javascript array concat then loop into one array

I have 4 arrays, I'd like to combine them into 1. I can do that, but I'd like to take one element from each array, push it to my new array, then get the next 4 and so on. This is what I got:
var a = [ "foo", "bar", "baz", "bam", "bun", "fun" ];
var b = [ 1, 2, 3, 4, 5, 6];
var c=["a","b","c","d","e","f"];
var d=[7,8,9,10,11,12]
var neat=[];
neat= a.concat(b, c,d);
//neat=["foo","bar","baz","bam","bun","fun",1,2,3,4,5,6,"a","b","c","d","e","f",7,8,9,10,11, 12]
The result I want would be something like this:
//neat=["foo",1,"a",7,"bar",2,"b",8...]
I'm not sure if a loop will work or if I need to use another function
Assuming each source array is the same length:
a.forEach((e, i) => {
neat.push(e, b[i], c[i], d[i]);
};
Please try the below code :
var a = [ "foo", "bar", "baz", "bam", "bun", "fun" ];
var b = [ 1, 2, 3, 4, 5, 6];
var c=["a","b","c","d","e","f"];
var d=[7,8,9,10,11,12]
var neat=[];
//neat= a.concat(b, c,d);
//neat=["foo","bar","baz","b
for (var i = 0; i < a.length ; i++)
{
neat.push(a[i], b[i], c[i], d[i]);
}
console.log(neat);
While Justins answer is correct, however if the lengths of the array are not the same every time, you could do
var maxItems = Math.max(a.length,b.length,c.length,d.length);
var neat = [];
for(var i = 0; i < maxItems; i++){
if(a[i] != undefined){
neat.push(a[i]);
}
if(b[i] != undefined){
neat.push(b[i]);
}
if(c[i] != undefined){
neat.push(c[i]);
}
if(d[i] != undefined){
neat.push(d[i]);
}
}
Math.max would find the biggest number of entries from between the 4 arrays, then a simple for loop on that number and check if the value is undefinedbefore pushing it to neat array.
See JSFiddle
Because the length of the all arrays are equal. So we can easily do that using loop.
var a = [ "foo", "bar", "baz", "bam", "bun", "fun" ];
var b = [ 1, 2, 3, 4, 5, 6];
var c=["a","b","c","d","e","f"];
var d=[7,8,9,10,11,12]
var neat=[], i;
for(i=0;i<a.length;i++){
neat.push(a[i]);
neat.push(b[i]);
neat.push(c[i]);
neat.push(d[i]);
}
console.log(neat);

Group identical values in array

I have an array that has some values inside, and I wish to return another array that has the value grouped in to their own arrays.
So the result I am trying to achieve is something like this:
var arr = [1,1,2,2,2,3,3,4,4,4,4,5,6]
var groupedArr =[[1,1],[2,2,2],[3,3],[4,4,4,4],[5],[6]]
This proposal works with Array#reduce for sorted arrays.
var arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 6],
groupedArr = arr.reduce(function (r, a, i) {
if (!i || a !== r[r.length - 1][0]) {
return r.concat([[a]]);
}
r[r.length - 1].push(a);
return r;
}, []);
document.write('<pre>' + JSON.stringify(groupedArr, 0, 4) + '</pre>');
Here you go. By the way, this works with unsorted array as well.
var arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 6]
var grpdArr = [];
while(arr.length > 0){
var item = arr[0];
grpdArr.push(arr.filter(function(val) {
return val === item;
}));
arr = arr.filter(function(val){return val!==item});
}
//console.log(arr, grpdArr);
Well this should do. Pretty straight forward..,
You get the elements and then remove them.
With forEach and temporary array
var arr = [1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 4, 5, 6];
var temp = [];
var res = [];
arr.forEach(function(e) {
if (temp.slice(-1) == e) temp.push(e);
else {
temp = [e];
res.push(temp);
}
});
document.write(JSON.stringify(res));
This may not be the most optimal version but should do. This also works for unsorted arrays.
function abc(arr) {
var newObj = new Object();
for (var i in arr) {
if (typeof newObj[arr[i]] == 'undefined') {
newObj[arr[i]] = new Array();
}
newObj[arr[i]].push(arr[i]);
}
var groupedArr = new Array();
for (i in newObj) {
groupedArr.push(newObj[i]);
}
return groupedArr;
}
console.log(abc([1, 1, 2, 2, 3, 3, 3, 4, 1]));
This is the most straightforward in my mind:
var arr = [1,1,2,2,2,3,3,4,4,4,4,5,6];
var grouped = {};
var groupedArr = [];
//accumulate the values in an object, each key is an array
for (var i = 0; i < arr.length; i++) {
if (!grouped[arr[i]]) grouped[arr[i]] = [];
grouped[arr[i]].push(arr[i]);
}
//loop through all the keys in the object and push the arrays to the master array
var keys = Object.keys(grouped);
for (var i = 0; i < keys.length; i++) {
groupedArr.push(grouped[keys[i]]);
}
console.log(groupedArr);
I think you could use the code below:
var arr = [1,1,2,2,2,3,3,4,4,4,4,5,6]
var groupedArray = [];
var temp = arr.sort();
var tempArray = [arr[0]];
for(var i = 0; i < temp.length - 1; ++i){
if(temp[i] == temp[i + 1]){
tempArray.push(temp[i + 1]);
}else{
groupedArray.push(tempArray);
tempArray = [temp[i + 1]];
}
}
groupedArray.push(tempArray);
Now the groupedArray will contain the Result

How to do a group by in Javascript

I have 2 arrays, a type array and an amount array:
var type = ["AB", "AB", "K1"];
var amt = [5, 2, 3];
I am having a difficult time grouping them together.
I want the output to be an array like below:
final_array = [{"AB", 7}, {"K1", 3}];
/* 7 and 3 are the sum of each type */
Note: I am guaranteed that both arrays will be the same size, and also guaranteed the order which means type[i] belongs with amt[i]. So from the example above type[0] which is "AB" belongs with amt[0] which is 5.
Thanks
This is written verbosely, but you'd use an object, and then iterate over one array checking if the keys exist in the object, if they do, just add the value to the sum, if they don't, set the value as the sum etc.
var type = [ "AB", "AB", "K1"];
var amt = [5, 2, 3];
var map = {};
type.forEach(function(x, i) {
if (x in map) {
map[x] += amt[i];
} else {
map[x] = amt[i];
}
});
document.body.innerHTML = '<pre>' + JSON.stringify(map, 0, 4) + '</pre>';
That leaves you with an object like {AB: 7, K1: 3}, which is probably what you want, but if you just have to have an array with objects that can't be looked up easily, you'd do
var arr = Object.keys(map).map(function(x) {
var o = {};
o[x] = map[x];
return o;
});
and you have [{"AB": 7}, {"K1": 3}]
var type = ["AB", "AB", "K1"];
var amt = [5, 2, 3];
var obj = {};
var final_array = [];
type.forEach(function(v, i) {
var t = obj[v];
if (t) {
t[v] += amt[i];
} else {
t = {};
t[v] = amt[i];
obj[v] = t;
}
});
Object.keys(obj).forEach(function(e) {
final_array.push(obj[e]);
});
document.write(JSON.stringify(final_array));

Removing an array of indexes from an given array

So I am having a bit of difficulty trying to think of the best way of doing this in javascript. I want to remove an array of unsorted indexes from an array that was X number of elements. For example
var index = [ 0, 7, 10, 2, 5, 11]
array = [{field0: 0}, {field1: 1}, {field2: 2}, ... {field5: 5}, {field6: 6}...]
So I tried using a nested for loop with splice, but then when I splice, my array loses its indexing and screws up.
The end result should come out to be like
array = [{field1: 1}, {field3: 3}, {field4: 4}, .... {field6: 6} ...]
Any help would be greatly appreciated.
The solution to your problem is really a one-liner:
array = [00,11,22,33,44,55,66,77];
indexes = [1,7,5,3];
array = array.filter(function(_,i) { return indexes.indexOf(i) < 0 });
document.write('<pre>'+JSON.stringify(array,0,3));
If sorting the array of elements to remove is not an issue, you can just do the following:
var array = [{field0: 0}, {field1: 1}, {field2: 2}, {field3: 3}, {field4: 4}, {field5: 5}, {field6: 6}, {field7: 7}, {field8: 8}, {field9: 9}];
var indices = [0, 7, 2, 5];
indices.sort(function(a, b) {
if ( a > b ) {
return 1;
} else if ( b > a ) {
return -1;
} else {
return 0;
}
});
for (var i = 0, offset = 0; i < indices.length; i++, offset++) {
array.splice(indices[i] - offset, 1);
}
console.log(array);
And if for some reason you were unable to sort the array of indices to remove, you could keep track of the offset with the following:
var array = [{field0: 0}, {field1: 1}, {field2: 2}, {field3: 3}, {field4: 4}, {field5: 5}, {field6: 6}, {field7: 7}, {field8: 8}, {field9: 9}];
var indices = [0, 7, 2, 5];
var removedIndices = [];
function calcOffset(val) {
var numRemoved = 0;
for (var j = 0; j < removedIndices.length; j++) {
if (val > removedIndices[j]) {
numRemoved++;
}
}
return numRemoved;
}
for (var i = 0, offset = 0; i < indices.length; i++, offset++) {
var offset = calcOffset(indices[i]);
array.splice(indices[i] - offset, 1);
removedIndices.push(indices[i]);
}
console.log(array);
I would iterate through array (for/next loop) and at each element see if the number exist in index (index.indexOf(n)). If it does, push the element to a new temporary array.
when you are done, either copy the temp array back to array OR array.length = 0 and push the elements from the temp array back onto the original array.
something like this:
var index = [ 0, 7, 10, 2, 5, 11]
var array = [{field0: 0}, {field1: 1}, {field2: 2},{field3: 3}, {field4: 4}];
var tempArray = [];
for(var arrayIndex = 0;arrayIndex < array.length;arrayIndex++){
if(index.indexOf(arrayIndex) === -1)
{
tempArray.push(array[arrayIndex]);
}
}
array = tempArray;
You can try deleting them with delete array[index[count]] by looping as long as undefined is not a problem.
Or, you can set loop through all the elements in the array and set any element whose index is not present to false. Then, loop through them again and copy only the ones which are not false to new array.
newArray = new Array();
for (var i = 0; i < array.length; i++) {
for(var j=0; j<index.length; j++) {
if (index[j] == i) {
array[i] = false;
}
}
};
for (var i = 0; i < array.length; i++) {
if (array[i] != false) {
newArray[i] = array[i];
}
}

Sort array using the positions

I've got an array as below.
var FruitArr = [5, "Mango", 3, "Apple", 2, "Lychee", 1, "Banana", 4, "Pineapple"];
How can I sort the fruit names according to the number before it and add to an empty array? The array has been stored as position , item.
The expected output is
var newFruitArr = ["Banana", "Lychee", "Apple", "Pineapple", "Mango"];
EDIT:
The reason for having items as it is shown: In my actual code the fruit names are base64 url string which is created on the fly. The base64 creating depends based on the image. Therefore I couldn't think of a better way of adding the url strings in to the array. So I added items to the array as 'desired position', 'base64 string'. I thought of sorting them once all conversions are done. I did use .splice() which did not work as expected because of the above reason.
There is no need to sort, you already have the indexes in your input array.
Just preallocate your new array and fill it.
var fruits = [2, "apple", 1, "orange"],
fruitsLength = fruits.length;
var newFruitArr = new Array(fruitsLength / 2);
for (var i = 0; i < fruitsLength; i += 2)
newFruitArr[fruits[i] - 1] = fruits[i + 1];
Does this fit your need ?
function sort (arr) {
var min, minId = -1, output = [];
while (arr.length >= 2) {
for (var i = 0; i < arr.length; i += 2) {
if (arr[i] < min || minId == -1) {
minId = i;
min = arr[i];
}
}
output.push(arr[minId + 1]);
arr.splice(minId, 2);
minId = -1;
}
return output;
}
It search for the minimum number, push the corresponding fruit to the output and remove the couple from the input array, until there's nothing in it. Quite simple, surely not the most effective solution.
You have to convert your array to a form easy to use with sort method.
Here is the code to do so:
var result = [];
FruitArr.forEach(function (el, i) {
if (i % 2) result.push({value: el, weight: FruitArr[i-1]});
});
The result array will be:
[{value: "Mango", weight: 5}, {value: "Apple", weight: 3}, {value: "Lychee", weight: 2}, {value: "Bananna", weight: 1}, {value: "Pineapple", weight: 4}];
which easy to sort with sort method.
I actually prefer insertion-sort-algo to sort an array because of performance issues:
var arr = [5, "Mango", 3, "Apple", 2, "Lychee", 1, "Bananna", 4, "Pineapple"];
var groups = [];
for(var f=0; f < arr.length; f+=2)groups.push([arr[f],arr[f+1]]);
function insertion_sort(array){
for(var o=1; o < array.length;o++){
for(var i=o; i>0 && array[i][0] < array[i-1][0];i--){
var tmp = array[i];
array[i] = array[i-1];
array[i-1] = tmp;
}
}
return array;
}
insertion_sort(groups); // [[1, "Bananna"], [2, "Lychee"], [3, "Apple"], [4, "Pineapple"], [5, "Mango"]]

Categories

Resources