JavaScript -- search for array values in object - javascript

I have an array and an array of objects. I want to search each value in the array in the array of objects and if it doesnt exist, I want to remove the value from the array.
var arr= [1,2,3,4];
var recs = [{id:1},{id:2},{id:3}]; //4 doesnt exist in recs, remove from arr
//arr = [1,2,3];
Heres my attempt. Obviously does not work. I am not sure how I can compare each arr index with all the values in recs before moving on the next arr index:
var arr= [1, 2, 3, 4], index;
var recs = [{a:1},{a:2},{a:3}];
for(var i = 0; i<arr.length; i++){
for(var val in recs[i]){
if(arr[i] != recs[i][val]){
index = arr.indexOf(arr[i]);
arr.splice(index, 1);
}
}
}
thank you!!

If you are okay with leaving your original array instance alone and creating a new one (essentially treating it as immutable)
var newArr = arr.filter(function(num) {
return !recs.every(function(obj) {
return obj.a !== num;
});
});
Detail of the methods used: Array.filter is passed a function, runs that function on each element inside, and then returns a new array with only the elements that returned true in the function.
Array.every works a little similar, but returns a Boolean, true or false. It returns true if all of the elements of the array returned true inside of the function.

var arr= [1, 2, 3, 4];
var recs = [{a:1},{a:2},{a:3}];
// don't use var in for loops.
// Variables declared with var have function scope, so declare them at the top of your function
var i;
var j;
var value;
var found;
// iterate over the array
for (i = 0; i < arr.length; i++)
{
value = arr[i];
found = false;
// iterate over the other array
for (j = 0 ; j < recs.length ; j++)
{
// if we found what we were looking for, make a note and exit loop
if (recs[j].a == value)
{
found = true;
break;
}
}
if (!found)
{
arr.splice(i, 1);
// To compensate the loop's i++, to avoid skipping the next entry
i--;
}
}
alert(arr.join(','));

Related

Array not reassigning after change

I have an array that contains elements my goal is to slice some of the elements inside the array, then later I want to reassign the original array with a new array which is a sublist of the original array but it seems like I can't make that happen please help.
let arr = [1,2,3,4,5]
function subList(arr){
for(let i = 0; i < arr.length; i++){
let res = arr.slice(0,i)
if(i === 3){
arr = res;
}
}
}
subList(arr)
console.log(arr)
// expected output [1,2,3]
There are a lot of ways to do it.
Why it isn't working for you:
You are passing the arr into the variable and since it is an object ideally any change you make to it should be reflected outside. But you aren't actually mutating/changing anything in your passed argument, you are reassigning it (with arr=res). So that will not make any change to the arr outside.
If you do something like .push(),.pop(), which are operations on the array without reassigning it, that should actually change it.
Example modifying your code with operations that actually modify the array instead of replacing it splice() , push:
let arr = [1,2,3,4,5]
function subList(arr){
for(let i = 0; i < arr.length; i++){
let res = arr.slice(0,i)
if(i === 3){
arr.splice(0,arr.length);
arr.push(...res);
break;
}
}
}
subList(arr)
console.log(arr)
Pass in an index to the function and just return arr.slice(0, i);.
let arr = [1, 2, 3, 4, 5]
function subList(arr, i) {
return arr.slice(0, i);
}
console.log(subList(arr, 3));
let list = [1,2,3,4,5]
function subList(arr,n){
for(let i = 0; i < arr.length; i++){
if(i === 3){
let res = arr.slice(0,i)
list = res;
}
}
}
subList(list,0)
console.log(list)

compare elements of array of many arrays

I trying to loop through an array of arrays, and compare the elements with each-other in-order to find the common elements. so lets say if we have var arr = [[1,2,3],[4,2,5]]; I want to first compare [i][i] and [i+1][i], [i][i+1] and [i+1][i+1] and [i][i+2] and [i+1][i+2] and so on. here is my code:
function sym(args) {
var fullArr = [];
var finalArr = [];
// store the arguments inside a single array
for (var count = 0; count < arguments.length; count ++) {
fullArr[count] = arguments[count];
}
// loop through finalArr[];
for (var i = 0; i < fullArr.length; i++) {
if (fullArr[i][i] == fullArr[i++][i++]) {
// if the element matches (it is a common element)
// store it inside finalArr
finalArr[i] = fullArr[i];
}
}
return finalArr;
}
sym([1, 2, 3], [5, 2, 1, 4]);
problem: when I run the code instead of an array containing the matching element, I get an empty array
You first have to iterate over one array and see if the other array includes the value you have specified.
My answer is similar to a nested for loop in that the includes method does exactly that. It takes in as a parameter an element and checks if the array which called it contains said element. In order to do that it must iterate through all elements in the array in the worst case.
My answer also assumes that you only want to count duplicate matches once.
function sym(args) {
var fullArr = [];
var finalArr = [];
// store the arguments inside a single array
for (var count = 0; count < arguments.length; count ++) {
fullArr[count] = arguments[count];
}
// loop through finalArr[];
//since you are comparing only two arrays in this
//example you just have to iterate over each element in the first array aka fullArr[0] and
//check if each element "e" is also in the second array aka fullArr[1]
//AND that your final output array does not already contain it.
//If both of these are true then we push the element to the output array.
fullArr[0].forEach(function(e){
if(fullArr[1].includes(e) && !finalArr.includes(e)) finalArr.push(e);
});
return finalArr;
}
sym([1, 2, 3], [5, 2, 1, 4]);
However if you want to check if a particular element exists in all collections of an n length array then I would propose something like this:
function sym(args) {
var fullArr = [];
var finalArr = [];
// store the arguments inside a single array
for (var count = 0; count < arguments.length; count ++) {
fullArr[count] = arguments[count];
}
var newArr = fullArr[0].reduce( function(prev, e1) {
if(prev.indexOf(e1) < 0 && fullArr.every( function(arr){
return arr.indexOf(e1) > -1;
})){
return [...prev, e1];
}else{
return prev;
};
},[]);
alert(newArr);
return newArr;
}
sym([1,1, 2, 3,4], [5, 2, 1, 4], [4,1,2, 5]);
You can iterate over the first array and check if any of its values are common through all the other arrays.
function sym() {
var common = [];
for (var i=0; i<arguments[0].length; i++) {
var isCommon = common.indexOf(arguments[0][i]) === -1; // first check if its not already exists in the common array
for (var j=1; j<arguments.length && isCommon; j++) {
isCommon = arguments[j].indexOf(arguments[0][i]) > -1
}
if (isCommon) common.push(arguments[0][i])
}
return common;
}
of course you can improve it by iterating over the smallest array.
In your code, when the following line executes, you also increment the value of i which is your control variable:
if (fullArr[i][i] == fullArr[i++][i++])
Thus, this is how your i variable gets incremented in each iteration:
Iteration #1: i = 0
Iteration #2: i = 3
- you get i+2 from the line that I mentioned above, +1 more from the increment that you specify in the final condition of the for loop
Therefore, even after the first iteration, your function will return an empty array on your particular scenario, as you are passing an array of length 3, and the for loop ends after i = 0 on the first iteration.
Even if the loop would go on, it would return an index out of bounds exception because your array of length 3 would not have an array[3] element.
For example, if you want to compare just two arrays, as in your scenario, you need to loop through each of them and compare their elements:
function sym(array1, array2) {
var results = [];
for (var i = 0; i < array1.length; i++) {
for (var j = 0; j < array2.length; j++) {
if(array1[i] === array2[j]) {
if(results.indexOf(array1[i]) === -1) {
results.push(array1[i]);
}
}
}
}
return results;
}
sym([1, 2, 3], [5, 2, 1, 4]);
I have also built a solution that returns the intersection of the arrays that you provide as the parameters for the function, regardless of how many arrays there are:
function sym(args) {
var paramSet = Array.prototype.slice.call(arguments);
var counterObject = {};
var results = [];
paramSet.forEach(function (array) {
// Filter the arrays in order to remove duplicate values
var uniqueArray = array.filter(function (elem, index, arr) {
return index == arr.indexOf(elem);
});
uniqueArray.forEach(function (element) {
if (Object.prototype.hasOwnProperty.call(counterObject, element)) {
counterObject[element]++;
} else {
counterObject[element] = 1;
}
});
});
for (var key in counterObject) {
if (counterObject[key] === paramSet.length) {
results.push(parseInt(key));
}
}
return results;
}
sym([1, 2, 3, 3, 3], [5, 2, 1, 4], [1, 7, 9, 10]);
The above code will return [1] for the example that I provided, as that is the intersection of all 3 arrays.

push to object if not exists from params

I've been trying and searching how to loop through the params to check if those already exist in an array, i haven't got it fully working but when there is a duplicate value it dose not return at all.
The idear is pass multiple values is param then loop through those vals and only push if it dose not exist in the array.
var arr = [7,3,1];
function pushNew(obj) {
var prams = obj;
for(var k = 0; k < obj.length; k++){
for (var i = 0; i < arr.length; i++) {
if (arr[i] == prams[k]) {
return;
}
}
array.push(prams[k]);
}
// console.info(arr);
}
pushNew([2,7,4]);
A short and more modern way to just get all the unique values is to use Array.from with Set. A Set is an array-like structure that will only hold unique values. Array.from converts an array-like structure into a real array.
In your case, you can just concat both arrays, pass them to Set to remove the duplicates, and use Array.from to convert it back to a regular array.
var arr1 = [1, 2, 3, 4, 5];
var arr2 = [3, 4, 5, 6, 7];
var result = Array.from(new Set(arr1.concat(arr2)));
document.write(JSON.stringify(result));
Actually, your existing code nearly works.
You can set a flag if you find a match in the inner loop and instead of return you should use break to escape the loop. Then use push after the inner loop if a match wasn't found. Also, there is no need for both obj and prams (which I've renamed to params), so:
var arr = [7,3,1];
function pushNew(params) {
var found;
for(var k=0; k<params.length; k++){
// Set found to initial value on each outer loop
found = false;
for (var i=0; i<arr.length; i++) {
// If find match, set flag and break from loop (for efficiency)
if (arr[i] == params[k]) {
found = true;
break;
}
}
// If match not found, push into arr
if (!found) arr.push(params[k]);
}
}
pushNew([7,2])
document.write(arr); // 7,3,1,2
If you want efficient code, consider creating an index and using in:
var arr = [7,3,1];
function addParams(params) {
var index = arr.reduce(function(acc, v) {
acc[v] = true;
return acc;
},{});
params.forEach(function(v) {
if (!(v in index)) arr.push(v);
});
}
addParams([7,3,2]);
document.write(arr);
You can use indexOf to validate if element is present in an array. forEach is another array method which works like loop.
var arr = [7,3,1];
function pushNew(obj) {
//var prams = obj;
obj.forEach(function(item){ // iterate through each element
if(arr.indexOf(item) == -1){ //indexOf return -1 is element is not present in an array
arr.push(item)
}
})
console.log(arr);
}
pushNew([2,7,4]);
Working Jsfiddle
var arr = [7, 3, 1];
function pushNew(obj) {
for (var k = 0; k < obj.length; k++) {
if (arr.indexOf(obj[k]) == -1) {
arr.push(obj[k]);
}
}
}
pushNew([2, 7, 4]);
You can use _.union function of lodash.
_.union([2, 1], [4, 2], [1, 2]);
// → [2, 1, 4]

Reversing certain number of elements in an array javascript

I am working on a code where I need to reverse certain no of elements in an array and rest should remain same. For example is an array has values of 1,2,3,4,5,6 and I have to reverse 4 elements of it then output should be 4,3,2,1,5,6. I am using below code to achieve this but getting error, please suggest.
function reverseArray(n, a) {
var interimArray1 = [];
//var interimArray2=[];
//var finalArray=[];
for (var i < n; i >= 0; i--) {
interimArray1.push[a[i]];
}
for (var i = n; i < a.length; i++) {
interimArray1.push[a[i]];
}
for (var i = 0; i < interimArray1.length; i++) {
console.log(interimArray1[i]);
}
}
var arr = [1, 2, 3, 4, 5, 6];
var num = 4;
reverseArray(num, arr);
The error in your code is that you intend to call the push method on a[i] like so:
interimArray1.push(a[i]);
but instead you write:
interimArray1.push[a[i]];
You make that mistake twice. To give arguments to the push method, you must use round parenthesis ().
With that fixed, you will see that your code works perfectly.
You can use Array#slice, Array#splice as follow.
function partialReverse(arr, num, from = 0) {
var slicedArr = arr.slice(from, num + from);
arr.splice(from, num); // Remove `num` items from array
arr.splice(from, 0, ...slicedArr.reverse()); // Add `num` reversed items
return arr;
}
var arr = [1, 2, 3, 4, 5, 6];
console.log(partialReverse(arr, 4, 0)); // Reverse four items from `arr` starting from 0th index
console.log(partialReverse(arr, 4, 1)); // Reverse four items from `arr` starting from 1st index
Lots of hints but you seem to be missing them. ;-)
You need to assign an initial value to i, so:
for (var i = n; ... )
===========^
Also, you need to use () to call functions, not [], so:
interimArray1.push(a[i]);
==================^====^
Same in the following for block. Otherwise, the code works though it's more verbose than it needs to be.
This is working :
I'm sure there are faster ways of doing it. Also, it will only work for elements at the beginning of the array but you can adjust the function for what you want to achieve.
var reverseArray = function(arr,elementsToReverse) {
var tempArrayRev = [];
var tempArray = [];
for (var i=0;i<arr.length;i++) {
if (i < elementsToReverse) {
tempArrayRev[i] = arr[i];
} else {
tempArray.push(arr[i]);
}
}
return tempArrayRev.reverse().concat(tempArray);
}
var array = [1,2,3,4,5,6];
document.getElementById('arrayOutput').innerHTML += reverseArray(array,4);
<div id="arrayOutput">Array :<br></div>
This is the answer you can test it.
function reverseArray(n, a) {
var interimArray1 = [];
for (var i = 0; i < a.length; i++) {
interimArray1.push(a[i]);
}
for (var i = num; i >=0; i--) {
interimArray1[i-1] = a[n - i];
}
for (var i = 0; i < interimArray1.length; i++) {
console.log(interimArray1[i]);
}
}
var arr = [1, 2, 3, 4, 5, 6];
var num = 4;
reverseArray(num, arr);
You could use something like this.
function reverseArray(n, arrIn) {
// Splice splits the array in 2 starting at 0 index going n long
var arrOut = arrIn.splice(0,n);
// reverse is pretty straight forward
arrOut = arrOut.reverse();
// Concat joins the two together
return arrOut.concat(arrIn);
}

Remove an item from a copy of an array without removing it from the original array

How can I remove an object from a copy of an array without removing it from the original?
I have a global variable :
var userTrickList = [];
And inside a function, I make a copy of that global array :
var tempUserTrickList = userTrickList;
Then I use the removeItem function that I created to remove a certain object.
removeItem(considerTrick.IDName, tempUserTrickList);
function removeItem(item, list) {
//takes a string as 'item', finds in the array as 'list',
//then removes it from the list.
for(var i = 0; i < list.length; i++)
{
if(item === list[i])
{
list.splice(i,1);
}
}
}
My problem is, this function removes it from the userTrickList too.
Any ideas? It's definitely a problem in "removeItem(considerTrick.IDName, tempUserTrickList);", but I can't think of a solution.
Use .slice(0) to clone an array.
var tempUserTrickList = userTrickList.slice(0);
Credits:
http://davidwalsh.name/javascript-clone-array
use this function for your requirement
function removeElementFromArray(data,target) {
var temp=new Array();
for ( var i = 0; i < data.length; i++) {
if(data[i]!=target){
temp.push(data[i]);
}
}
return temp; }
here data is original array and target is the element you want to remove from array
this function will return array without containing the removed item.
Try, It copy the original array
var tempUserTrickList = JSON.parse(JSON.stringify(userTrickList));
Demo CopyArray
for (i = 0, l = arr.length; i < l; i++) {
if (arr[i] === item) {
arr.splice(i, 1);
i -= 1;
l -= 1;
}
}
Daniel's method of cloning an array is absolutely correct, but since I don't see an ES6-oriented answer, I'll offer up an alternative solution:
We can just as easily use the spread operator to clone an array, so we don't have to use the slice call.
const arr = [1, 2, 3];
const copy = [...arr];
copy.pop();
console.log(arr); // returns [1, 2, 3]
console.log(copy); // returns [1, 2]

Categories