Checking whether certain item is in certain array using javascript - javascript

I have 10 different arrays. Each array has different numbers.
array1 = [1,2,3,4,5]
array2 = [6,7,8,9,10]
...
array 10 = [51,52,53,54]
let's say I pass in 7. Then I want to know which array it is from and want to return array number. So in this case it is going to be 2.
Should I write a switch statement for each array? Appreciate it in javascript.

try:
var arrays = [array1, array2, ..., array10];
for(var i=0; i<arrays.length; ++i) {
if (arrays[i].indexOf(value) != -1) {
console.log('found in array' + (i+1));
}
}

You cannot directly retrieve the name of array.The reason is this variable is only storing a reference to the object.
Instead you can have a key inside the same array which represent its name. Then indexOf can be used to find the array which contain the number , & if it is so, then get the array name
var array1 = [1,2,3,4,5];
array1.name ="array1";
var array2 = [6,7,8,9,10];
array2.name ="array2";
var array10 = [51,52,53,54]
array10.name ="array10";
var parArray = [array1,array2,array10]
function _getArrayName(number){
for(var o=0;o<parArray.length;o++){
var _tem = parArray[o];
if(parArray[o].indexOf(number) !==-1){
console.log(parArray[o].name);
}
}
}
_getArrayName(6) //prints array2
jsfiddle

One fast method should be using hash tables or as i would like to call LUT. Accordingly this job boils down to a single liner as follows;
var arrs = {
arr1 : [1,2,3,4,5],
arr2 : [6,7,8,9,10],
arr3 : [12,14,16,17],
arr4 : [21,23,24,25,27,20],
arr5 : [31,34,35,39],
arr6 : [45,46,44],
arr7 : [58,59],
arr8 : [66,67,69,61],
arr9 : [72,73,75,79,71],
arr0 : [81,85,98,99,90,80]
},
lut = Object.keys(arrs).reduce((p,c) => {arrs[c].forEach(n => p[n]=c); return p},{}),
findar = n => lut[n];
document.write("<pre>" + findar(12) + "</pre>");

One way to do this is have the arrays in an object and iterate over the keys/values. This method doesn't presume the arrays (and therefore their names) are in sequential order.
Note: this will always return a the first match from the function and terminate the search.
var obj = {
array1: [1, 2, 3, 4, 5],
array2: [6, 7, 8, 9, 10],
array3: [51, 52, 53, 54],
array4: [51, 52, 53, 54, 7]
}
function finder(obj, test) {
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (obj[key].indexOf(test) > -1) {
return key.match(/\d+/)[0];
}
}
return false;
}
finder(obj, 7); // '2'
DEMO
If you want to find all instances of a value in all arrays the function needs to be altered slightly.
function finder(obj, test) {
var keys = Object.keys(obj);
var out = [];
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (obj[key].indexOf(test) > -1) {
out.push(key.match(/\d+/)[0]);
}
}
return out;
}
finder(obj, 7); // ['2', '4']
DEMO

Related

javascript sorting 2D array makes duplicates in my array

I am trying to sort my 2D array according to column 3.
when I sort it with sort function, all the array members become duplicates of one member of the original array.
so for example;
my original array:
[12, AAA, eee, 5]
[58, BBB, zzz, 3]
[28, CCC, ddd, 6]
[18, DDD, fff, 9]
I want it to become :
[18, DDD, fff, 9]
[28, CCC, ddd, 6]
[12, AAA, eee, 5]
[58, BBB, zzz, 3]
I use the code :
function sortByColumn(a, colIndex){
a.sort(sortFunctionq);
function sortFunctionq(a, b) {
if (a[colIndex] === b[colIndex]) {
return 0;
}
else {
return (a[colIndex] > b[colIndex]) ? -1 : 1;
}
}
return a;
}
var sorted_a = new Array(15);
sorted_a = sortByColumn(arr, 3);
now the array becomes:
[18, DDD, fff, 9]
[18, DDD, fff, 9]
[18, DDD, fff, 9]
[18, DDD, fff, 9]
I am using javascript on Samsung Gear watch. maybe it does not support the "sort" function correctly.
is there a way to sort 2D array without using sort function ?
final code is:
var sorted_a = new Array(15);
sorted_a = sortByColumn(arrx, 3);
arrx= sorted_a;
function bubbleSort(a, fCompare) {
if( a.length < 2) {return a;}
for( var length = a.length-1; length; --length) {
var noSwaps = true;
var temp;
for(var c=0; c<length; ++c) {
if( fCompare( a[c], a[c+1]) > 0) {
temp = a[c+1];
a[c+1] = a[c];
a[c] = temp;
noSwaps = false;
}
}
if( noSwaps) {break;}
}
}
function sortByColumn(a, colIndex){
function sortFunctionq(a, b) {
if (a[colIndex] === b[colIndex]) {
return 0;
}
else {
return (a[colIndex] > b[colIndex]) ? -1 : 1;
}
}
//return bubbleSort(a, sortFunctionq);
return bubbleSort(a.slice(), sortFunctionq);
}
but now nothing is available in the array.
for those who ask:
if I remove the sort function and use arrx as it is, I can reach 2D array elements with arrx[1][1]
but with the code above arrx[1][1] returns null.
I changed it a bit and now it seems to work.
But now I need to remove duplicates as well. How can I do that ?
current code:
var arrx = new Array(50);
for (var j = 0; j<50; j++){
arrx[j] = arr[j].split("|+");
}
var arry = new Array(50);
arry = bubbleSort(arrx);
function bubbleSort(a) {
for( var r = 49; r >= 0; --r) {
var noSwaps = true;
var temp = new Array(50);
for(var c=0; c<r; ++c) {
if (a[c][3] < a[c+1][3]) {
temp = a[c+1];
a[c+1] = a[c];
a[c] = temp;
noSwaps = false;
}
}
if( noSwaps) {break;}
}
return a;
}
The direct answer to you question is "yes, it is possible to sort an array without using the array's sort method". A simple example using bubble sort:
function bubbleSort(a, fCompare) {
if( a.length < 2)
return a;
for( var length = a.length-1; length; --length) {
var noSwaps = true;
var temp;
for( i=0; i<length; ++i) {
if( fCompare( a[i], a[i+1]) > 0) {
temp = a[i+1];
a[i+1] = a[i];
a[i] = temp;
noSwaps = false;
}
}
if( noSwaps)
break;
}
}
function sortByColumn(a, colIndex){
function sortFunctionq(a, b) {
if (a[colIndex] === b[colIndex]) {
return 0;
}
else {
return (a[colIndex] > b[colIndex]) ? -1 : 1;
}
}
return bubbleSort(a, sortFunctionq);
}
var a = [
[12, 'AAA', 'eee', 5],
[58, 'BBB', 'zzz', 3],
[28, 'CCC', 'ddd', 6],
[18, 'DDD', 'fff', 9],
];
var sortedA = sortByColumn(a,2) // updates a in-place, as well
console.log( JSON.stringify(sortedA))
However
Note that both the sort method of an array and the bubbleSort above change the order of elements in the array being sorted, without creating a shallow copy of the array. While bubbleSort may show the Samsung JS engine has a problem, more than likely it will not and produce the same result.
Because sorting sorts the array in place, you may wish to check if creating a shallow copy of it before sorting solves the problem. EG by replacing the return statement in the example with
return a.slice().sort(functionq) // OR
return bubbleSort(a.slice(), functionq)
Debugging notes:
JavaScript arrays are objects. The value of an object variable is a reference of some kind used by the JavaScript engine to access object properties. The reference could be a memory pointer or some other value used by the engine to access object data. When you assign an object to a variable, its existing content is overwritten. If you assign the same object value to two variables, they hold the same refernce value and refer to the same set of object data.
var arry = new Array(50);
arry = bubbleSort(arrx);
unnecessarily creates a new Array, because the new Array value is overwritten in the second line. It can be simplified as
var arry = bubbleSort( arrx).
Note that JavaScript arrays can grow and shrink and do not have some pre-allocated length.
Both the bubble sort code and the inbuilt array sort method (inherited by an array instance from the Array.prototype object, and documented on MDN under Array.prototype.sort) sort the array in place and return an object reference to the array being sorted. After
arry = bubbleSort(arrx); // OR
arry = arrx.sort(sortFunction)
the value of arry is the same as arrx. If you want to make a copy of the array that is immune to arrx modificatioms of first dimension values, make a shallow copy of the input array before sorting:
arry = bubbleSort(arrx.slice());
If you want to make a copy that is immune to modifications to either dimension value then make a shallow copy of both dimensions' arrays as for example:
arry = bubbleSort( arrx.map(element => element.slice())
This creates new arrays from both dimensions of arrx before sorting.
If you are still getting duplicate entries after this you will need to find out where in the code the duplicates are being assigned.
Tip
Check there are no typos in conditional tests that use = (the assignment operator) instead of == or === operators to test for equality. This is a good way of inadvertently assigning values to something that was not meant to be changed.
All you need to change is to return the sorted array.
const data = [
[12, 'AAA', 'eee', 5],
[58, 'BBB', 'zzz', 3],
[28, 'CCC', 'ddd', 6],
[18, 'DDD', 'fff', 9]
];
function sortByColumn(a, colIndex){
function sortFunctionq(a, b) {
if (a[colIndex] === b[colIndex]) {
return 0;
}
else {
return (a[colIndex] > b[colIndex]) ? -1 : 1;
}
}
return a.sort(sortFunctionq);
//^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
const result = sortByColumn(data, 3);
console.log(result);

Return numbers which appear only once (JavaScript)

Say I have the array [1,2,3,5,2,1,4]. How do I get make JS return [3,4,5]?
I've looked at other questions here but they're all about delete the copies of a number which appears more than once, not both the original and the copies.
Thanks!
Use Array#filter method twice.
var data = [1, 2, 3, 5, 2, 1, 4];
// iterate over elements and filter
var res = data.filter(function(v) {
// get the count of the current element in array
// and filter based on the count
return data.filter(function(v1) {
// compare with current element
return v1 == v;
// check length
}).length == 1;
});
console.log(res);
Or another way using Array#indexOf and Array#lastIndexOf methods.
var data = [1, 2, 3, 5, 2, 1, 4];
// iterate over the array element and filter out
var res = data.filter(function(v) {
// filter out only elements where both last
// index and first index are the same.
return data.indexOf(v) == data.lastIndexOf(v);
});
console.log(res);
You can also use .slice().sort()
var x = [1,2,3,5,2,1,4];
var y = x.slice().sort(); // the value of Y is sorted value X
var newArr = []; // define new Array
for(var i = 0; i<y.length; i++){ // Loop through array y
if(y[i] != y[i+1]){ //check if value is single
newArr.push(y[i]); // then push it to new Array
}else{
i++; // else skip to next value which is same as y[i]
}
}
console.log(newArr);
If you check newArr it has value of:
[3, 4, 5]
var arr = [1,2,3,5,2,1,4]
var sorted_arr = arr.slice().sort(); // You can define the comparing function here.
var nonduplicates = [];
var duplicates=[];
for (var i = 0; i < arr.length; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
duplicates.push(sorted_arr[i]);
}else{
if(!duplicates.includes(sorted_arr[i])){
nonduplicates.push(sorted_arr[i]);
}
}
}
alert("Non duplicate elements >>"+ nonduplicates);
alert("Duplicate elements >>"+duplicates);
I think there could exists option with Map.
function unique(array) {
// code goes here
const myMap = new Map();
for (const el of array) {
// save elements of array that came only once in the same order
!myMap.has(el) ? myMap.set(el, 1) : myMap.delete(el);
}
return [...myMap.keys()];
}
const array = [1,2,3,5,2,1,4];
//[11, 23, 321, 300, 50, 23, 100,89,300];
console.log(unique(array));

JavaScript: Convert [a,b,c] into [a][b][c]

I have arrays like [a], [a,b], [a,b,c] and so on.
How can I convert them into [a], [a][b], [a][b][c] and so on?
Example:
var arr = [1,2,3,4];
arr = do(arr); // arr = arr[1][2][3][4]
You could map it with Array#map.That returns an array with the processed values.
ES6
console.log([1, 2, 3, 4].map(a => [a]));
ES5
console.log([1, 2, 3, 4].map(function (a) {
return [a];
}));
While the question is a bit unclear, and I think the OP needs possibly a string in the wanted form, then this would do it.
console.log([1, 2, 3, 4].reduce(function (r, a) {
return r + '[' + a + ']';
}, 'arr'));
Functional:
use .map like this
[1,2,3,4].map(i => [i])
Iterative:
var list = [1, 2, 3, 4], result = [];
for (var i=0; i<list.length; i++) {
result.push([list[i]]);
}
If I understand you correctly, you are converting single dimension array to multi dimensional array.
To do so,
var inputArray = [1,2,3,4];
var outputArray = [];
for(var i=0;i<inputArray.length;i++)
{
outputArray.push([inputArray[i]])
}
function map(arr){
var aux = [];
for(var i=0; i<arr.length;++i){
var aux2 = [];
aux2.push(arr[i]);
aux.push(aux2);
}
return aux;
}

Sort Object Containing Multiple Arrays: JavaScript [duplicate]

for hours i've been trying to figure out how to sort 2 array dependently.
Let's say I have 2 arrays.
First one:
array1 = ['zzzzz', 'aaaaaa', 'ccccc'];
and the second one:
array2 = [3, 7, 1];
I sort the first one with array1.sort(); and it becomes [aaaaaa, cccccc, zzzzzz]
now what I want is that the second one becomes [7, 1, 3]
I think it's quite simple but i'm trying to implement this in something a little more complex, im new and i keep mixing up things.
Thanks
I would "zip" them into one array of objects, then sort that with a custom sort callback, then "unzip" them back into the two arrays you wanted:
var array1 = ['zzzzz', 'aaaaaa', 'ccccc'],
array2 = [3, 7, 1],
zipped = [],
i;
for(i=0; i<array1.length; ++i) {
zipped.push({
array1elem: array1[i],
array2elem: array2[i]
});
}
zipped.sort(function(left, right) {
var leftArray1elem = left.array1elem,
rightArray1elem = right.array1elem;
return leftArray1elem === rightArray1elem ? 0 : (leftArray1elem < rightArray1elem ? -1 : 1);
});
array1 = [];
array2 = [];
for(i=0; i<zipped.length; ++i) {
array1.push(zipped[i].array1elem);
array2.push(zipped[i].array2elem);
}
alert('Sorted arrays:\n\narray1: ' + array1 + '\n\narray2: ' + array2);
Here's a working fiddle.
Here's a simple function that will do the trick:
function sortTogether(array1, array2) {
var merged = [];
for(var i=0; i<array1.length; i++) { merged.push({'a1': array1[i], 'a2': array2[i]}); }
merged.sort(function(o1, o2) { return ((o1.a1 < o2.a1) ? -1 : ((o1.a1 == o2.a1) ? 0 : 1)); });
for(var i=0; i<merged.length; i++) { array1[i] = merged[i].a1; array2[i] = merged[i].a2; }
}
Usage demo (fiddle here):
var array1 = ['zzzzz', 'aaaaaa', 'ccccc'];
var array2 = [3, 7, 1];
console.log('Before..: ',array1,array2);
sortTogether(array1, array2); // simply call the function
console.log('After...: ',array1,array2);
Output:
Before..: ["zzzzz", "aaaaaa", "ccccc"] [3, 7, 1]
After...: ["aaaaaa", "ccccc", "zzzzz"] [7, 1, 3]
Instead of two arrays of primitive types (strings, numbers) you can make an array of objects where one property of the object is string (containing "aaaaa", "cccccc", "zzzzzz") and another is number (7,1,3). This way you will have one array only, which you can sort by any property and the other property will remain in sync.
It just so happens I had some old code lying around that might do the trick:
function arrVirtualSortGetIndices(array,fnCompare){
var index=array.map(function(e,i,a){return i;});
fnCompare=fnCompare || defaultStringCompare;
var idxCompare=function (aa,bb){return fnCompare(array[aa],array[bb]);};
index.sort(idxCompare);
return index;
function defaultStringCompare(aa,bb){
if(aa<bb)return -1;
if(bb<aa)return 1;
return 0;
}
function defaultNumericalCompare(aa,bb){
return aa-bb;
}
}
function arrReorderByIndices(array,indices){
return array.map(
function(el,ix,ar){
return ar[indices[ix]];
}
);
}
var array1 = ['zzzzz', 'aaaaaa', 'ccccc'];
var array2 = [3, 7, 1];
var indices=arrVirtualSortGetIndices(array1);
var array2sorted=arrReorderByIndices(array2,indices);
array2sorted;
/*
7,1,3
*/
Sorry, I don't do 'fors'. At least not when I don't have to.
And fiddle.
Also, an alternative fiddle that sorts the results when given an array of objects like this:
given:
var list = [
{str:'zzzzz',value:3},
{str:'aaaaa',value:7},
{str:'ccccc',value:1}
];
outputs:
[
{str: "aaaaa", value: 7},
{str: "ccccc", value: 1},
{str: "zzzzz", value: 3}
]
Assumption:
The arrays are the same length (this is implied by your question)
the contents can be compared with > and < (true in your example, but I wanted to make it clear that it was assumed here)
So then we can use an insertion sort.
var value,len = array1.length;
for (i=0; i < len; i++) {
value = array1[i];
for (j=i-1; j > -1 && array1[j] > value; j--) {
array1[j+1] = array1[j];
array2[j+1] = array2[j];
}
items[j+1] = value;
}
Using a solution found here to find the new indices after sorting an array, you can apply those indices to array2 like so.
function sortWithIndices(toSort) {
for (var i = 0; i < toSort.length; i++) {
toSort[i] = [toSort[i], i];
}
toSort.sort(function(left, right) {
return left[0] < right[0] ? -1 : 1;
});
toSort.sortIndices = [];
for (var j = 0; j < toSort.length; j++) {
toSort.sortIndices.push(toSort[j][2]);
toSort[j] = toSort[j][0];
}
return toSort;
}
var array1 = ['zzzz', 'aaaa', 'cccc'];
var array2 = [3, 7, 1];
// calculate the indices of array1 after sorting. (attached to array1.sortIndices)
sortWithIndices(array1);
// the final array after applying the sorted indices from array1 to array2
var final = [];
// apply sorted indices to array2
for(var i = 0; i < array1.sortIndices.length; i++)
final[i] = array2[array1.sortIndices[i]];
// output results
alert(final.join(","));
JSFiddle Demo

How to join two arrays into one two-dimensional array?

I have two arrays. How can I join them into one multidimensional array?
The first array is:
var arrayA = ['Jhon, kend, 12, 62626262662',
'Lisa, Ann, 43, 672536452',
'Sophie, Lynn, 23, 636366363'];
My other array has the values:
var arrayB = ['Jhon', 'Lisa', 'Sophie'];
How could I get an array with this format??
var jarray = [['Jhon', ['Jhon, kend, 12, 62626262662']],
['Lisa', ['Lisa, Ann, 43, 672536452']],
['Sohphie', ['Sophie, Lynn, 23, 636366363']]]
var jarray = [];
for (var i=0; i<arrayA.length && i<arrayB.length; i++)
jarray[i] = [arrayB[i], [arrayA[i]]];
However, I wouldn't call that "multidimensional array" - that usually refers to arrays that include items of the same type. Also I'm not sure why you want the second part of your arrays be an one-element array.
Here is a map version
const arrayA = ['Jhon, kend, 12, 62626262662',
'Lisa, Ann, 43, 672536452',
'Sophie, Lynn, 23, 636366363'];
const arrayB = ['Jhon', 'Lisa', 'Sophie'];
/* expected output
var jarray = [['Jhon', ['Jhon, kend, 12, 62626262662']],
['Lisa', ['Lisa, Ann, 43, 672536452']],
['Sohphie', ['Sophie, Lynn, 23, 636366363']]] */
const jarray = arrayB.map((item,i) => [item,[arrayA[i]]]);
console.log(jarray);
You can use Underscore.js http://underscorejs.org/#find
Looks through each value in the list, returning the first one that passes a truth test (iterator). The function returns as soon as it finds an acceptable element, and doesn't traverse the entire list.
var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; });
=> 2
Then, you can make the same with the array B elements and by code, make a join.
This is what I did to get what you were asking:
var jarray = [];
for (var i = 0; i < arrayB.length; i++) {
jarray[i] = [];
jarray[i].push(arrayB[i]);
var valuesList = [],
comparator = new RegExp(arrayB[i]);
for (var e = 0; e < arrayA.length; e++) {
if (comparator.test(arrayA[e])) {
valuesList.push(arrayA[e]);
}
}
jarray[i].push(valuesList);
}

Categories

Resources