search for array inside an array - javascript

I need to search for the presence of an array inside an array. It is similar to jQuery.inArray function.
For
var a = [ [1,2], [1,3] ];
console.log( jQuery.inArray([1,3],a ) )
I get -1 as ans. How to do this?
Thank you

In V8 (that is, Chrome), there is a nifty trick: while == does not work for arrays, <= && >= does.
You can iterate and check for each item if it's appearent:
for(var i = 0; i < a.length; i++) {
if(a[i] >= [1, 3] && a[i] <= [1, 3]) alert(i);
}
For other browsers, you'd need a function that checks for array equality:
http://www.svendtofte.com/code/usefull_prototypes/prototypes.js
Array.prototype.compareArrays = function(arr) {
if (this.length != arr.length) return false;
for (var i = 0; i < arr.length; i++) {
if (this[i].compareArrays) { //likely nested array
if (!this[i].compareArrays(arr[i])) return false;
else continue;
}
if (this[i] != arr[i]) return false;
}
return true;
}
Then:
for(var i = 0; i < a.length; i++) {
if(a[i].compareArrays([1, 3])) alert(i);
}

function inArray (needle, haystack) {
for (var idx in haystack) {
if (haystack[idx].join(',') == needle.join(','))
return idx;
}
return -1;
}

try this
function look4arr(arr, v) {
for (var i = 0, l = arr.length; i < l; i += 1) {
if (arr[i].toString() === v.toString()) { //or use +''
return true;
}
}
return false;
}
var a = [[1,2], 2],
ok = [1,2],
ko = [2,3]
look4arr(a, ok); // true
look4arr(a, ko); // false
// as far as the array you are looking at contains primitives seem to work fine
if you need to search for something "more" ...I mean object literals, regexp, functions
You could use a function similar to the following one
function look4x(arr, v) {
for (var i = 0, isObjOrArray = false, l = arr.length; i < l; i += 1) {
isObjOrArray = {}.toString.call(arr[i]).match(/\[object\s(Array|Object)\]/);
if (
(isObjOrArray && JSON.stringify(arr[i])+'' == JSON.stringify(v)+'' )
||
(!isObjOrArray && arr[i].toString() === v.toString())
) {
return true;//or i if a jQuery.inArray output is needed
}
}
return false; // or -1 ... if ... jQuery.inArray
}
var a = [
[1,[1,[1,[1,2]]]],
2,
true,
'hei',
Infinity,
{"o" : "s", 'd':[1,2,3]},
new RegExp(/\s/),
function(){alert('hei');}
],
ok = [1,[1,[1,[1,2]]]];
alert(
look4x(a, [1,[1,[1,[1,2]]]])
&&
look4x(a, true)
&&
look4x(a, 'hei')
&&
look4x(a, Infinity)
&&
look4x(a, {"o" : "s", 'd':[1,2,3]})
&&
look4x(a, new RegExp(/\s/))
&&
look4x(a, function(){alert('hei');})
); // true, in this case
Please note that I didn`t tested it yet with a complete test; I'll post a test asap
Event if I seem to be late, hope it can help someone.
Bye

Related

JavaScript Elements of array being equal function not working

While taking some online JS tests, I am stuck on why my function for testing if the elements within two arrays are equal is not working. I am using the function to make sure that the new array does not have duplicate values.
The following is my function for testing if the elements of the arrays are equal or not:
const isEqualArr = (a, b) => {
for (let i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
};
I call to the function within a for loop, then I test for undefined, because the first time around, the outputArr is empty
for (let x = 0; x < numsLength; x++) {
if (typeof outputArr[x] != 'undefined') {
if (isEqualArr(tempArr, [outputArr[x]])) {
However, the result shows that there are duplicates:
0: Array [ -1, 0, 1 ]
​
1: Array [ -1, 2, -1 ]
​
2: Array []
​
3: Array [ -1, -1, 2 ]
​
4: Array []
​
5: Array [ 0, 1, -1 ]
​
6: Array [ 0, -1, 1 ]
​
7: Array [ 1, 0, -1 ]
​
8: Array [ -1, 0, 1 ]
The other issue is that not only do I have two null arrays (duplicates), but when I test for null before the push, it is not working either:
if(tempArr != null ) {
outputArr.push(tempArr);
}
I have tried tempArr[0] != null, tempArr[0] != '' as well as
if (typeof tempArr[0] != 'undefined')
But it still inserts null arrays into the outputArr.
The following is the premise of the test:
Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, and j != k, and nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets. Given nums = [-1,0,1,2,-1,-4]
The following code is my solution, but the duplicate entries, as well as the null entries, makes this an incorrect solution. If you guys can see why my isEqualArr function is at fault, then I would appreciate it.
const threeSum = (nums) => {
let numsLength = nums.length;
let tempArr = [];
let outputArr = [];
if (numsLength > 3) {
for (let i = 0; i < numsLength; i++) {
for (let j = 1; j < numsLength; j++) {
for (let k = 2; k < numsLength; k++) {
if (
i != j &&
i != k &&
j != k &&
nums[i] + nums[j] + nums[k] == 0
) {
tempArr[0] = nums[i];
tempArr[1] = nums[j];
tempArr[2] = nums[k];
for (let x = 0; x < numsLength; x++) {
if (typeof outputArr[x] != 'undefined') {
if (!isEqualArr(tempArr, [outputArr[x]])) {
if (typeof tempArr[0] != 'undefined') {
outputArr.push(tempArr);
console.log(
'temp: ' + tempArr + ' outputArr: ' + outputArr[x]
);
console.log(
'compare: ' + isEqualArr(tempArr, outputArr[x])
);
console.log(outputArr);
tempArr = [];
}
}
}
}
if (i == 0) {
outputArr.push(tempArr);
tempArr = [];
} else {
// do nothing
}
}
}
}
}
}
return outputArr;
};
const isEqualArr = (a, b) => {
for (let i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
};
EDIT: I was able to eliminate the null entries by moving the code that checks if it is the first time to run above the for loop:
if (i == 0) {
outputArr.push(tempArr);
tempArr = [];
} else {
// do nothing
}
for (let x = 0; x < numsLength; x++) {
if (typeof outputArr[x] != 'undefined') {
if (!isEqualArr(tempArr, [outputArr[x]])) {
if (typeof tempArr[0] != 'undefined') {
outputArr.push(tempArr);
console.log(
'temp: ' + tempArr + ' outputArr: ' + outputArr[x]
);
console.log(
'compare: ' + isEqualArr(tempArr, outputArr[x])
);
console.log(outputArr);
tempArr = [];
}
}
}
}
BTW, another thing that is not working if the following logic:
i != j &&
i != k &&
j != k &&
You can see by the outputArr that this logic is being completely ignored.
REFACTORED: even though the online test marked my solution as wrong, you can see with the results, that it is correct. Especially when you factor in the conditionals for making sure that nums[i] != nums[j] and so forth:
const threeSum = (nums) => {
let numsLength = nums.length;
let tempArr = [];
let outputArr = [];
for (let i = 0; i < numsLength; i++) {
for (let j = 0; j < numsLength; j++) {
for (let k = 0; k < numsLength; k++) {
if (
nums[i] != nums[j] &&
nums[i] != nums[k] &&
nums[j] != nums[k] &&
nums[i] + nums[j] + nums[k] == 0
) {
if (typeof outputArr[0] != 'undefined') {
/**********
* if it reaches this conditional
* then outputArr has at least one element
***********/
if (typeof outputArr[k] != 'undefined') {
tempArr[0] = nums[i];
tempArr[1] = nums[j];
tempArr[2] = nums[k];
if (isEqualArr(tempArr, outputArr)) {
// do nothing because there is already an element within the array
} else {
outputArr.push(tempArr);
// empty tempArr after insert
tempArr = [];
}
}
} else {
// push triplet elements into temp array for the first iteration only
tempArr[0] = nums[i];
tempArr[1] = nums[j];
tempArr[2] = nums[k];
// insert tempArr for the first iteration only
outputArr.push(tempArr);
// empty tempArr after insert
tempArr = [];
}
}
}
}
}
return outputArr;
};
const isEqualArr = (a, b) => {
for (elem in b) {
for (let i = 0; i < a.length; i++) {
if (a[i] != elem[i]) {
// do nothing
} else {
return true;
}
}
}
return false;
};
RESULTS:
(3) [Array(3), Array(3), Array(3)]
0: (3) [-1, 0, 1]
1: (3) [1, 0, -1]
2: (3) [-1, 1, 0]
length: 3
Your inner for loop is confusing, if you replace it by a forEach you can see what's going on, you should pass as argument outputArr[x] not [outputArr[x]] and there's more stuff.
const threeSum = (nums) => {
let numsLength = nums.length;
let tempArr = [];
let outputArr = [];
if(numsLength < 3) return;
for (let i = 0; i < numsLength; i++) {
for (let j = 1; j < numsLength; j++) {
for (let k = 2; k < numsLength; k++) {
if (
i != j &&
i != k &&
j != k &&
nums[i] + nums[j] + nums[k] == 0
) {
tempArr.push(nums[i], nums[j], nums[k]); // push three at the same time, it's cleaner and avoid problems
outputArr.forEach((arr, index) => {
if(!isEqualArr(arr, outputArr[index])) outputArr.push(tempArr); // outputs correctly
});
if (i == 0) {
outputArr.push(tempArr);
tempArr = [];
}
}
}
}
}
return outputArr;
};
const isEqualArr = (a, b) => {
for (let i = 0; i < a.length; i++) {
if (a[i] != b[i]) {
return false;
}
}
return true;
};
console.log(threeSum([-1,0,1,2,-1,-4]));

Check if the next item is 1 unit longer (Javascript)

I am a coding beginner and I was writing the following function that checks if the next string of a given array is one unit longer:
function canBuild(arr) {
for(let i = 0; i < arr.length; i++) {
if (i == arr.length-1) { return true }
if (arr[i].length+1 != arr[i+1].length) { return false }
}
}
desired output:
canBuild(["a", "at", "ate", "late", "plate", "plates"]) ➞ true
canBuild(["it", "bit", "bite", "biters"]) ➞ false
// "biters" is 2 units longer than the previous string
I was wondering if there is a more efficient and shorter way to write the same function, if someone explained me other ways to do so I would really appreciate it!
Use every method and some temp variable (x here)
const canBuild = (arr) => (
(x = arr[0]?.length), arr.every((c) => c.length === x++)
);
console.log(canBuild(["a", "at", "ate", "late", "plate", "plates"]));
console.log(canBuild(["it", "bit", "bite", "biters"]));
function canBuild(arr) {
for(let i = 0; i < arr.length; i++) {
if(i+1 != arr[i].length)
return false;
}
return true;
}
This is a O(n) solution.
function canBuild(arr) {
for(let i = 0; i < arr.length; i++) {
if(i > 0 && arr[i].length !== arr[i-1].length+1)
return false;
}
return true;
}
EDIT: even better, as suggeste by Thomas:
function canBuild(arr) {
for(let i = 1; i < arr.length; i++) {
if(arr[i].length !== arr[i-1].length+1)
return false;
}
return true;
}

Deleting certain elements from an array in Javascript

I am trying to code a program that will remove any zeros, empty strings, null, or undefined values in an array. However when I run this array: [1,null,2,3,0,-1,1.1], through the code below it returns the array with the null and 0 value still in the array. Any help?
function cleanArray(arr) {
var i = 0;
for (i; i < arr.length; i++) {
if (arr[i] === 0 || arr[i] === '' || arr[i] === null || arr[i] === undefined) {
arr.splice(i, 1);
i--;
}
return arr;
}
}
Because of return arr;, which you have placed inside your for loop. As soon as the code runs through the first element, it hits the return and leaves the function with the array as it was after the first run of the loop.
Just move the return statement outside the for loop, like so:
function cleanArray(arr) {
var i = 0;
for (i; i < arr.length; i++) {
if (arr[i] === 0 || arr[i] === '' || arr[i] === null || arr[i] === undefined) {
arr.splice(i, 1);
i--;
}
}
return arr;
}
You need to move return arr; outside the for loop.
function cleanArray(arr) {
var i = 0;
for (i; i < arr.length; i++) {
if (arr[i] === 0 || arr[i] === '' || arr[i] === null || arr[i] === undefined) {
arr.splice(i, 1);
i--;
}
}
return arr;
}
Use .filter() and the falsy value to remove the unwanted items
function cleanArray(arr) {
return arr.filter(function (item) {
return !!item;
//or return arr[i] !== 0 && arr[i] !== '' && arr[i] !== null && arr[i] !== undefined
})
}
very simplistically,
arr = arr.filter(function(item) {
return !!item;
});
but that would let true and other non numeric values through
arr = arr.filter(function(item) {
return !!item && !isNaN(item);
});
may work better (haven't tested it myself - leaves you with something to try)
You can make use of array filter
var arr = [1,null,2,3,0,-1,1.1];
var filteredArr = arr.filter(function(i){
// if in javascript checks for truthy values
if(i) {
return i;
}
});
console.log(filteredArr); // [1, 2, 3, -1, 1.1]
Demo here
function cleanArray(arr) {
var i = 0, newArr = [];
for (i; i < arr.length; i++) {
if (arr[i]) {
newArr.push(arr[i]);
}
}
return newArr;
}
This will work for sure. Hope I was helpful.
Here the fiddle: https://jsfiddle.net/rok_ed/coakcd3L/

Filter Array Before Push JSON Object to Javascript

it looks like easy but I kind of stuck in trying to figure out how to filter data before pushing json data into javascript array.
//push data into javascript array [timestamp,value]
dataJSON2 = [];
for (i in parsed2) {
if (parsed2[i].value == 'open' || parsed2[i].value == 'true' ) {
thevalue = 1;
} else if (parsed2[i].value == 'closed' || parsed2[i].value == 'false' ) {
thevalue = 0;
} else {
thevalue = parsed2[i].value;
}
dataJSON2.push( [ (parsed2[i].timestamp),
parseFloat (thevalue) ] );
}
what I am trying to accomplish is if current thevalue var is the same with the previous thevalue then it would discard the data and go to the next i until it return different value.
It would be easy if using for looping but I don't know different way to push json object rather than for..in, nor to use filtering i value before pushing it.
var dataJSON2 = [], previous;
for (i in parsed2) {
if (parsed2[i].value === 'open' || parsed2[i].value === 'true' ) {
thevalue = 1;
} else if (parsed2[i].value === 'closed' || parsed2[i].value === 'false' ) {
thevalue = 0;
} else {
thevalue = parsed2[i].value;
}
if (previous === thevalue) continue;
previous = thevalue;
dataJSON2.push( [ (parsed2[i].timestamp), parseFloat (thevalue) ] );
}
This would check for previous value with the current value and skip it if they are same
dataJSON2 = [];
var lastVal = parsed2 && parsed2[0];
for (var i = 1; i < parsed2.length; i++) {
if (lastVal !== parsed2[i].value) {
dataJSON2.push([(parsed2[i].timestamp), parseFloat(parsed2[i].value)]);
lastVal = parsed2[i];
}
}
Extracted from Array.indexOf from MDN
Create a function like this
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
'use strict';
if (this == null) {
throw new TypeError();
}
var n, k, t = Object(this),
len = t.length >>> 0;
if (len === 0) {
return -1;
}
n = 0;
if (arguments.length > 1) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
for (k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
};
}
and use indexOf like this
if (dataJSON2.indexOf( [ (parsed2[i].timestamp), parseFloat (thevalue) ] ) == -1){
dataJSON2.push( [ (parsed2[i].timestamp), parseFloat (thevalue) ] );
}

remove string element from javascript array

can some one tell me how can i remove string element from an array
i have google this and all i get is removing by index number
my example :
var myarray = ["xyz" , "abc" , "def"] ;
var removeMe = "abc" ;
myarray.remove(removeMe) ;
consle.log(myarray) ;
this is what i get from the console :
Uncaught TypeError: Object xyz,abc,def has no method 'remove'
​
jsfiddle
Since you're using jQuery
myarray.splice($.inArray("abc", myarray), 1);
EDIT
If the item isn't in the array, this 'one-liner' will likely throw an error. Something a little better
var index = $.inArray("abc", myarray);
if (index>=0) myarray.splice(index, 1);
From https://stackoverflow.com/a/3955096/711129:
Array.prototype.remove= function(){
var what, a= arguments, L= a.length, ax;
while(L && this.length){
what= a[--L];
while((ax= this.indexOf(what))!= -1){
this.splice(ax, 1);
}
}
return this;
}
var ary = ['three', 'seven', 'eleven'];
ary.remove('seven')
or, making it a global function:
function removeA(arr){
var what, a= arguments, L= a.length, ax;
while(L> 1 && arr.length){
what= a[--L];
while((ax= arr.indexOf(what))!= -1){
arr.splice(ax, 1);
}
}
return arr;
}
var ary= ['three','seven','eleven'];
removeA(ary,'seven')
You have to make a function yourself. You can either loop over the array and remove the element from there, or have this function do it for you. Either way, it is not a standard JS feature.
Try like below,
myarray.splice(myarray.indexOf(removeMe),1);
You can add this below script (from MDN) for browsers that doesn't support indexOf
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function (searchElement /*, fromIndex */ ) {
"use strict";
if (this == null) {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
if (len === 0) {
return -1;
}
var n = 0;
if (arguments.length > 0) {
n = Number(arguments[1]);
if (n != n) { // shortcut for verifying if it's NaN
n = 0;
} else if (n != 0 && n != Infinity && n != -Infinity) {
n = (n > 0 || -1) * Math.floor(Math.abs(n));
}
}
if (n >= len) {
return -1;
}
var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
for (; k < len; k++) {
if (k in t && t[k] === searchElement) {
return k;
}
}
return -1;
}
}
more simple solution
var myarray = ["xyz" , "abc" , "def"];
var removeMe = "abc";
var theNewArray = myarray.filter(s => s !== removeMe);
console.log(theNewArray); // will return ["xyz" , "def"]

Categories

Resources