Making subarrays from an array algorithm javascript [duplicate] - javascript

I have a JavaScript array with 8 elements and some elements are repeating. I want to create separate arrays for identical elements.
example:
original array is [1,1,1,3,3,1,2,2]
resulting arrays will be [1,1,1,1],[3,3],[2,2]
I want a function similar to this:
var array=[1,1,1,3,3,1,2,2];
var createNewArrays=function(array){
for (var i = 0; i < array.length; i++) {
for (var j = 0; j < array.length; j++) {
}
}
};

You could use a hash table as reference to the sub arrays for the collection.
var array = [1, 1, 1, 3, 3, 1, 2, 2],
result = [];
array.forEach(function (a) {
a in this || result.push(this[a] = []);
this[a].push(a);
}, Object.create(null));
console.log(result);

var arr = [1,1,1,3,3,1,2,2];
var hash = Object.create(null);
var result = arr.reduce(function(r, n) {
if(!hash[n]) {
hash[n] = [];
r.push(hash[n]);
}
hash[n].push(n);
return r;
}, []);
console.log(result);
And an ES6 solution that uses Map, and spread:
const arr = [1,1,1,3,3,1,2,2];
const result = [...arr.reduce((r, n) =>
r.set(n, (r.get(n) || []).concat(n)),
new Map()).values()];
console.log(result);

Let's assume you want the resulting arrays to be properties on an object keyed by the value they represent. You just loop through the array, creating or adding to the arrays on the object properties as you go:
var array=[1,1,1,3,3,1,2,2];
var result = {};
array.forEach(function(entry) {
(result[entry] = result[entry] || []).push(entry);
});
console.log(result);
That's a bit dense, here's a clearer version:
var array=[1,1,1,3,3,1,2,2];
var result = {};
array.forEach(function(entry) {
var subarray = result[entry];
if (!subarray) {
subarray = result[entry] = [];
}
subarray.push(entry);
});
console.log(result);

Related

how to create json with two array in javascript

I have two json:
I want to create json with those two array;
var __columns = ["Field1", "Field2", "Field3", "Field4"];
var __rows = ["valueField1_1", "valueField2_1", "valueField3_1", "valueField4_1", "valueField1_2", "valueField2_2", "valueField3_2", "valueField4_2", "valueField1_3", "valueField2_3", "valueField3_3", "valueField4_3"];
The thing is that I wanna create something like this
var json = [{
"Field1":"valueField1_1",
"Field2":"valueField2_1",
"Field3":"valueField3_1",
"Field4":"valueField4_1"
},{
"Field1":"valueField1_2",
"Field2":"valueField2_2",
"Field3":"valueField3_2",
"Field4":"valueField4_2"
},{
"Field1":"valueField1_3",
"Field2":"valueField2_3",
"Field3":"valueField3_3",
"Field4":"valueField4_3"
}]
ES6 solution using Array.from and Array#reduce methods.
var __columns = ["Field1", "Field2", "Field3", "Field4"];
var __rows = ["valueField1_1", "valueField2_1", "valueField3_1", "valueField4_1", "valueField1_2", "valueField2_2", "valueField3_2", "valueField4_2", "valueField1_3", "valueField2_3", "valueField3_3", "valueField4_3"];
var res = Array.from({
// generate array with particular size
length: __rows.length / __columns.length
// use map function to generate array element
}, (_, i) => __columns.reduce((obj, e, i1) => {
// define object property based on the index values
obj[e] = __rows[i * __columns.length + i1];
return obj;
// set empty object as initial argument
}, {}));
console.log(res);
function convertToJsonArr(__columns, __rows){
var obj = {};
var arr = [];
var len = __columns.length;
var count = 0;
$.each(__rows , function(key, value){
if(count >= len){
count = 0;
arr.push(obj);
obj = {};
}
obj[__columns[count++]] = value;
})
arr.push(obj);
return arr;
}
you can call like convertToJsonArr(__columns, __rows);
One way to achieve this is using loops
var __columns = ["Field1", "Field2", "Field3", "Field4"];
var __rows = ["valueField1_1", "valueField2_1", "valueField3_1", "valueField4_1", "valueField1_2", "valueField2_2", "valueField3_2", "valueField4_2", "valueField1_3", "valueField2_3", "valueField3_3", "valueField4_3"];
var arr = [];
for(var i = 0; i < __rows.length; i = i + __columns.length){
var tempObj = {};
for(var j = 0; j < __columns.length; ++j){
tempObj[__columns[j]] = __rows[i];
}
arr.push(tempObj);
}
console.log(arr);

Javascript, comparing two arrays in order while skipping non-matching indexes

I have two arrays:
var arr1 = [1,2,3,4,5]
var arr2 = [7,1,8,2,12,3,4,28,5]
I need to go through arr2 looking for matches to arr1, but it has to be in order (1,2,3,4,5). As you can see in arr2, the order does exists, but there are some numbers in between.
[7,1,8,2,12,3,4,28,5]
I have about 50 arrays similar to arr2, so I need to look through each one, and when I find a match, push it out to a "results" object. Small issue though is that some arrays will not have the entire match, may only have 1,2,3 or any variation of the search. Also, if the array I'm searching in is NOT in order, (IE: starts at 2,3,4) skip over it entirely.
The idea is to loop through these arrays, and when I find a match, add a count to the results array.
For example, using arr1 as the search, go through these arrays:
[7,1,8,2,12,3,4,28,5],
[7,1,8,2,12,3,4],
[7,8,1,2],
[1,2,3]
and have a result that looks like this (a dictionary of what was searched for, and a count of what was found) :
{1:4, 2:4, 3:3, 4:2, 5:1}
I tried doing a bunch of for-loops, but I can't figure out how to skip over a number that I'm not looking for, and continue onto the next iteration, while saving the results into a dictionary object.
let list = [[7,1,8,2,12,3,4,28,5], [7,1,8,2,12,3,4], [7,8,1,2], [1,2,3]];
let search = [1, 2, 3, 4, 5];
// Initialize result with zeros:
let result = search.reduce((result, next) => {
result[next] = 0;
return result;
}, {});
// Increment result for items found:
list.forEach(array => {
for (let i = 0, j = 0; i < array.length && j < search.length; ++i) {
if (array[i] == search[j]) {
++result[search[j]];
++j;
}
}
});
console.log(result);
Essentially this:
var needle = [1,2,3,4,5]
var collection = [[7,1,8,2,12,3,4,28,5], [7,1,8,2,12,3,4], [7,8,1,2], [1,2,3]]
// start with an object
var results = {}
// populate object with zeros
needle.forEach(function (i) { results[i] = 0 })
// define an index to iterate through collection
var i = 0
// define an index to conditionally iterate through "arr1"
var j = 0
// define an index to iterate through collection arrays
var k = 0
// define surrogate for the arrays in the collection
var arr
while (i < collection.length) {
// get collection array
arr = collection[i]
// reset the indices
j = 0
k = 0
while (k < arr.length) {
// if same element on needle is in a collection array
if (needle[j] === arr[k]) {
// save it in an object starting at 1
results[needle[j]]++
j++ // increment needle
}
k++ // increment array in collection
}
i++ // increment collection
}
console.log(results) // {1:4, 2:4, 3:3, 4:2, 5:1}
I hope that helps!
var arr1 = [1,2,3,4,5];
var arr2 = [7,1,8,2,12,3,4,28,5];
function givenTwoArrays(a,b, obj){
var obj = obj || {};
var cond = true;
function otherMatch(indexFound,elementFound){
var indexOnA = a.indexOf(elementFound);
return a.some(function(ele, idx){
if(idx > indexOnA)
return b.some(function(bele,bidx){
return ele == bele && bidx < indexFound;
});
});
}
a.map(function(aele,idx){
if(cond){
var indexFound = b.findIndex(function(bele){
return aele == bele;
});
if(typeof indexFound !== 'undefined'){
if(!otherMatch(indexFound,aele)){
if(typeof obj[aele] !== 'undefined')
obj[aele]++;
else{
obj[aele] = 1;
}
} else {
cond = false;
}
}else
cond = false;
}
});
return obj;
}
console.log("first pass");
console.log(givenTwoArrays(arr1,arr2))
console.log("second pass");
console.log(givenTwoArrays(arr1,arr2,{
"1": 1,
"2": 1,
"3": 1,
"4": 1,
"5": 1
}));
I think this will work, just need to add a little recursion!
var orign = [1,2,3,4,5];
var arr = [[7,1,8,2,12,3,4,28,5], [7,1,8,2,12,3,4], [7,8,1,2], [1,2,3]];
//temp result
var arrTmp = [];
for (var x in arr){
var match = 0;
var mis = 1;
var curIndex = 0;
var cur = orign[curIndex];
var arrTmpX = [];
for(var y in arr[x]){
if(arr[x][y] !== cur){
mis=1;
}else{
//add match after mismatch
arrTmpX.push(cur);
curIndex++
cur = orign[curIndex];
}
}
arrTmp.push(arrTmpX);
}
//calc result
var result = {};
for (var x in orign){
result[orign[x]] = 0;
for(var y in arrTmp){
if(arrTmp[y].length>x)result[orign[x]]++;
}
}
console.log(result);
this works

Sort object array based on another array of keys

I have two arrays containing objects. One contains keys in some order and another has data and I need to sort the data array in order against the given sorted key array. How can I do this?
var a = ['d','a','b','c'] ;
var b = [{a:1},{c:3},{d:4},{b:2}];
The result should be:
result = [{d:4},{a:1},{b:2},{c:3]
Try this
var a = ['d','a','b','c'] ;
var b = [{a:1},{c:3},{d:4},{b:2}];
b.sort(function(x,y){
var xkey = a.indexOf(Object.keys(x)[0]);
var ykey = a.indexOf(Object.keys(y)[0]);
return xkey - ykey;
})
document.body.innerHTML += JSON.stringify(b,0,4);
A different approach from above ones would be, using Lodash Javascript Library.
var a = ['d','a','b','c'] ;
var b = [{a:1},{c:3},{d:4},{b:2}];
var results = _.map(a,function(av) {
var obj = {};
obj[av] = _.find(b, av)[av];
return obj
});
document.body.innerHTML += JSON.stringify(results);
<script src="https://cdn.jsdelivr.net/lodash/4.11.1/lodash.min.js"></script>
This approach respects the keys in the objects of the array for sorting.
Only the items of a are used for lookup and their respective order.
In this case d gets all sort value of the item of b, so d looks like
[ 1, 3, 0, 2 ]
While sorting with indices, we need e, which has simply the indices of b
[ 0, 1, 2, 3 ]
after sorting it became
[ 2, 0, 3, 1 ]
the wanted sort order. Now the original array is remapped to the new order.
But why?
Usually objects contains more than one property. If you use Object.keys and take just the first element, then you could go wrong, because this element is not the wanted element for getting the sort order.
To make it save, you need a different approach, which does not use Array#indexOf in combination with a fixed item of Object.keys.
var a = ['d', 'a', 'b', 'c'],
b = [{ a: 1 }, { c: 3 }, { d: 4 }, { b: 2 }],
d = b.map(function (bb) {
var k = -1;
a.some(function (aa, i) {
if (aa in bb) {
k = i;
return true;
}
});
return k;
}),
e = b.map(function (_, i) { return i; });
e.sort(function (a, b) {
return d[a] - d[b];
});
b = e.map(function (a) {
return b[a];
});
document.write('<pre> ' + JSON.stringify(b, 0, 4) + '</pre>');
This should do the trick
result = a.map(function(key) {
for(var i=0; i<b.length; ++i) {
if(key in b[i]) return b[i];
}
});
Brute force approach is to loop through each of a array and check the b array for it's presence.
var a = ['d','a','b','c'] ;
var b = [{a:1},{c:3},{d:4},{b:2}];
var ans = [];
for(var i = 0; i < a.length; ++i)
{
for(var j = 0; j < b.length; ++j)
{
if(b[j][a[i]])
ans.push(b[j]);
}
}
document.write(JSON.stringify(ans, 0, 4));

Modify an object to a new Array in Javascript

sorry, i m a beginner in javascript.
Can someone explain me how to modify this Object
{toto:[12,13,15],titi:[45,12,34]}
to this Array
newArray = [
{
toto:12,
titi:45
},{
toto:13,
titi:12
},{
toto:15,
titi:34}
]
Also, what the solution if the toto and titi doesn't have the same lenght
Thanks for support!
Here's how I did it. In this way, you don't need to know the names of the keys or the size of the array, but it does require a few loops.
obj = {toto:[12,13,15],titi:[45,12,34]};
newArray = [];
// Find the longest array in your data set
longest = 0;
Object.keys(obj).forEach(function(key) {
if (obj[key].length > longest) {
longest = obj[key].length;
}
});
// Loop through the existing data set to create new objects
for (i = 0; i<longest; i++) {
newObject = {};
Object.keys(obj).forEach(function(key) {
newObject[key] = obj[key][i];
});
newArray.push(newObject);
}
console.log(newArray);
plnkr.co demo in the script.js file.
If you want to ignore keys that would have undefined values for uneven loops, you can add a conditional inside the forEach loop that creates a new object:
Object.keys(obj).forEach(function(key) {
if (obj[key][i] !== undefined) {
newObject[key] = obj[key][i];
}
});
Assuming lengths of toto and titi are the same:
Obj = {toto:[12,13,15],titi:[45,12,34]};
newArray = [];
for (var k in Obj["toto"]) {
newArray.push({ toto:Obj["toto"][k],titi:Obj["titi"][k] });
}
Since the lengths of your inner arrays are equal, you should be able to simply loop through them and add a value from each array (for each iteration) into a new array :
// Your input
var input = {toto:[12,13,15],titi:[45,12,34]};
// An array to store your output
var output = [];
// Since your inner arrays are of equal size, you can loop through them
// as follows
for(var i = 0; i < input.toto.length; i++){
output.push({ toto: input.toto[i], titi: input.titi[i]});
}
You can see a working example of this here and what the output array looks like below :
A more generic approach
var object = { toto: [12, 13, 15], titi: [45, 12, 34] },
newArray = function (o) {
var keys = Object.keys(o),
l = keys.reduce(function (r, a) { return Math.max(r, o[a].length); }, 0),
i = 0,
t,
result = [];
while (i < l) {
t = {};
keys.forEach(function (k) { t[k] = o[k][i]; });
result.push(t);
i++;
}
return result;
}(object);
document.write('<pre>' + JSON.stringify(newArray, 0, 4) + '</pre>');

How to access elements of arrays within array (JavaScript)?

I'm trying to access elements from a JavaScript array:
[["1","John"],["2","Rajan"],["3","Hitesh"],["4","Vin"],["5","ritwik"],["6","sherry"]]
I want to access
1, 2, 3, 4, 5, 6 separately in a variable and John, Rajan, Hitesh, Vin, Ritwik, Sherry separately in a variable.
I tried converting it to a string and split(), but it doesn't work.
this is code i tried
var jArray = <?php echo json_encode($newarray); ?> ;
var nJarr = jArray[0]; nJarr.toString();
var res = nJarr.split(","); var apname = res[0];
alert(apname);
but there's no alert appearing on the screen
If you are open to using Underscore, then it's just
var transposed = _.zip.apply(0, arr);
and the arrays you are looking for will be in transposed[0] and transposed[1].
You can write your own transpose function fairly easily, and it's more compact if you can use ES6 syntax:
transpose = arr => Object.keys(arr[0]).map(i => arr.map(e => e[i]));
>> transpose([["1","John"], ["2","Rajan"], ...]]
<< [[1, 2, ...], ["John", "Rajan", ...]]
If you want an ES5 version, here's one with comments:
function transpose(arr) { // to transpose an array of arrays
return Object.keys(arr[0]) . // get the keys of first sub-array
map(function(i) { // and for each of these keys
arr . // go through the array
map(function(e) { // and from each sub-array
return e[i]; // grab the element with that key
})
))
;
}
If you prefer old-style JS:
function transpose(arr) {
// create and initialize result
var result = [];
for (var i = 0; i < arr[0].length; i++ ) { result[i] = []; }
// loop over subarrays
for (i = 0; i < arr.length; i++) {
var subarray = arr[i];
// loop over elements of subarray and put in result
for (var j = 0; j < subarray.length; j++) {
result[j].push(subarray[j]);
}
}
return result;
}
Do it like bellow
var arr = [["1","John"],["2","Rajan"],["3","Hitesh"],["4","Vin"],["5","ritwik"],["6","sherry"]];
var numbers = arr.map(function(a){return a[0]}); //numbers contain 1,2,3,4,5
var names = arr.map(function(a){return a[1]}); //names contain John,Rajan...
Try this:
var data = [["1","John"],["2","Rajan"],["3","Hitesh"],["4","Vin"],["5","ritwik"],["6","sherry"]];
var IDs = [];
var names = [];
for(i=0; i<data.length; i++)
{
IDs.push(data[i][0]);
names.push(data[i][1]);
}
console.log(IDs);
console.log(names);
Here is the working fiddle.

Categories

Resources