Mix contents of 2 arrays - javascript

I have 2 array:
var arr1 = [1, 1, 2, 3, 4, 4];
var arr2 = [];
arr1 defines some groups, the group members are defined by the position. So the group members 0 and 1 belong to group 1,
member 2 belong to group 2,
member 3 belong to group 3,
the group member 4 and 5 belong to group 4.
I would like to load the groups with their members into another array, so that I looks like:
arr2 = [[0,1], [2], [3], [4,5]];
So group 1 has the members 0 and 1 and so on...
When doing:
for(i=0; i<arr1.length; i++){
arr2[arr1[i]] = i;
}
I get:
arr2 = [1: 1, 2: 2, 3: 3, 4: 5];

You've almost gotten it right, but you need to create an array for each index in arr2, and then append i to it:
for(i=0; i<arr1.length; i++){
arr2[arr1[i]] = arr2[arr1[i]] || []; // create array here if none exists yet
arr2[arr1[i]].push(i) // add i to array
}
Note that this produces an of-by-one difference from your desired solution (the first group will be at index 1, rather than index 0 in your solution), so you can shift the indicies of arr2 down by one:
for(i=0; i<arr1.length; i++){
arr2[arr1[i]-1] = arr2[arr1[i]-1] || [];
arr2[arr1[i]-1].push(i)
}
Note that you have not specified your desired behavior if there would be a gap in the arr2 result. In this case, the index remains unset in the output array.

You need to create new array for each group and then push values to it. See my comments in code below:
var arr1 = [1, 1, 2, 3, 4, 4];
var arr2 = [];
for(i=0; i<arr1.length; i++) {
// array indexes begins from 0, therefore arr2[arr1[i] - 1]
if (!arr2[arr1[i] - 1]) { // if array for this index does not exist
// then initialize new empty array
arr2[arr1[i] - 1] = [];
}
arr2[arr1[i] - 1].push(i); // push correct value to the array
}

var i;
var arr2 = [];
for(i=0; i<arr1.length; i++){
arr2[arr1[i]-1] = arr2[arr1[i]-1] || [];
arr2[arr1[i]-1].push(i);
}

Related

How can I iterate & match the values from two different sized arrays until the longer array has been exhausted?

Say I have two arrays with the following values:
let array1 = (1,2,3,4);
let array2 = (1,2,3,4,5,6,7,8);
How do I exhaustively assign the values from array2 so that all of them are assigned to a key from array1; like so:
let result = (
1: {1,5},
2: {2,6},
3: {3,7},
4: {4,8},
);
If there were 9 values in array 2 then it would continue looping until:
let result = (
1: {1,5,9},
2: {2,6},
3: {3,7},
4: {4,8},
);
In my real-world example, array1 will be minutes, so {1..60}, array2 will be an unknown number of dates (more than 60). I want to continue assigning the unknown number of dates a key until all dates are assigned a minute key from 1-60.
Unless I misunderstand your question, one way to accomplish this is to implement array1 as a simple 2D array: an array of arrays.
let array1 = [[1],[2],[3],[4]];
let array2 = [1,2,3,4,5,6,7,8,9];
let row = 0;
let column = 0;
for (count = 0; count < array2.length; count++) {
if (row >= array1.length) {
row = 0;
column++;
}
array1[row][column] = array2[count];
row++;
}
consol.log(array1);
Try this quickly by going to the url "about:blank" and then right click somewhere and click inspect. Go to the console tab and paste the code above and press enter. Click the arrow from the output to expand the array and you should find that it worked as required. Also, not that it matters in your case, but this method of using the >= comparison instead of using % is faster for the task.
Try this:
let array1 = [1, 2, 3, 4];
let array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let result = [];
for(let i=0; i<array1.length; i++) {
result[i] = [];
for(let j=i; j<array2.length; j=j+array1.length) {
result[i].push(array2[j]);
}
}
console.log(result);

Comparing an array to an array set in JavaScript

I want to compare an array with an array set.
For example,
array 1 = [[1,2,3],[1,4,5]];
array 2 = [1,3,6,5,4];
Since the elements 1,4,5 in array 2 match with a set in array 1 it should return true.
use loop and loop. get all child array in array1, and check each child array include in array2.
function check(){
var array1 = [[1,2,3],[1,4,5]];
var array2 = [1,3,6,5,4];
for(let arr of array1){
let flag=true;
for(let child of arr){
if(array2.indexOf(child) < 0){
flag = false;
break; // if one element not in array2, enter next loop.
}
}
if(flag) return flag; // if got one child array elements all in array2, stop loop.
}
}
Iterate over your array and check if the value exists in the other array.
var sets = [
[1, 2, 3],
[1, 4, 5]
],
valid = [1, 3, 6, 5, 4];
var processed = sets.map(set => set.every(val => valid.includes(val)));
console.log( processed);
There are ways to make this more efficient, but try this for starters.
Here's an example how you can check if any are true:
// Check if any are true
var any = processed.some(v=>v);
console.log( any );
You can iterate over array1 and use every() on each number group and as a condition for it use includes() with the second array for a relatively short syntax:
var array1 = [
[1, 2, 3],
[1, 4, 5]
];
var array2 = [1, 3, 6, 5, 4];
var results = [];
array1.forEach(function(item, index, array) {
if (item.every(x => array2.includes(x))) {
results.push(item)
}
});
console.log(results)
Edited : I'm pushing the results that return true to an empty array ...
Flatten the first array (unpack the nested arrays). Then do an intersection of the flattened array and the second array. Map through the first array, and for each each array do an intersection against the second array. Then filter out all arrays that are empty. If the resulting array contains something, then something matched.
const hasMatch = Boolean(array1.map(a => intersect(a, array2)).filter(i => i.length).length)
var array1 = [
[1, 2, 3],
[1, 4, 5]
];
var array2 = [1, 3, 6, 5, 4];
var isMatch = doesNestedArrayMatchArray(array1, array2);
function doesNestedArrayMatchArray(nestedArray, bigArray) {
var atLeastOneMatch = false;
for (var i = 0; i < nestedArray.length; i++) {
var innerMatch = true;
//go through each array of array1
for (var j = 0; j < nestedArray[i].length; j++) {
if (bigArray.indexOf(nestedArray[i][j]) == -1){
innerMatch = false;
break;
}
}
if (innerMatch) atLeastOneMatch = true;
}
return atLeastOneMatch;
}
console.log(isMatch)

JS code to return n times an array not working

The following coding problem has me stumped. There are four tests, which begin with "// ex." They are followed by my code. My code is only passing the first test. I am unsure why it is failing the next 3. Thanks in advance for any insight.
// 1.4 repeat(n, array)
// Write a function that takes a non-negative integer n and an array and returns a new
// array that contains the contents of given array repeated n times.
// ex. repeat(0, [1]) -> []
// ex. repeat(10, []) -> []
// ex. repeat(1, [1, 2, 3]) -> [1, 2, 3]
// ex. repeat(3, [1, 2, 3]) -> [1, 2, 3, 1, 2, 3, 1, 2, 3]
toolbox.repeat = function(n, array) {
var arr = [];
for(var i = 0; i < n; i++){
arr.push(array);
}
return arr;
}
Your problem is this line:
arr.push(array);
What this does is pushes the entire array as a single element, so you get:
[ [], [], ... n times ]
But what you want to do is push the contents of the array, n times.
One way you can solve this is to, instead of pushing, you concat array to arr on each iteration:
arr = arr.concat(array);
Another way would be to call Array.prototype.push and pass arr as the context into which to push and array as the arguments to be pushed:
Array.prototype.push.apply(arr, array);
Or in ES6 you can use the spread operator to do the same:
arr.push(...array)
As self demonstrated, you can also create an inner loop to, for every n, iterate over array and add its elements to arr.
You should use array.concat instead
var repeat = function(n, array) {
var arr = []
for(var i = 0; i < n; i++){
arr = arr.concat(array);
}
return arr;
}
console.log(repeat(3,[1,2,3]))
It looks like you need to push every value of array onto your new array n times. So you'll have an inner loop of:
var repeat = function(n, array) {
var arr = [];
for(var i = 0; i < n; i++) {
for(var j = 0; j < array.length; j++) {
arr.push(array[j]);
}
}
console.log(arr);
}
repeat(0, [1])
repeat(10, [])
repeat(1, [1, 2, 3])
repeat(3, [1, 2, 3])
your code is incorrect, please change a little bit to
toolbox.repeat = function(n, array) {
var arr = [];
for(var i = 0; i < n; i++) {
// use concat array instead
arr = arr.concat(array);
return arr;
}
// repeat(0, [1]) -> []
// repeat(10, []) -> []
// repeat(1, [1, 2, 3]) -> [1, 2, 3]
// repeat(3, [1, 2, 3]) -> [1, 2, 3, 1, 2, 3, 1, 2, 3]

Filtering arrays of complex objects with loops

I have two arrays of complex nexted objects that I'm looking for qualifying values within using loops and if statements as seen below. When I find a qualifying object, I need to filter that object out during the next go around of the loop. I'm trying to do that with an array as you can see here but it isn't working as the array starts over during each iteration of the loop. The following version is a simplified version of my code.
I want to update the values in array2 based on the if statement so that those values are not repeated in the nested loop. Instead my emptyArray remains empty instead of adding values from the array2 as elements of array2 are equal to elements of array.
To be clear, right now emptyArray remains empty and never filters array2. I'd like to see emptyArray collect value 2 at the start of the outer loop's second iteration then I'd like to see emptyArray collect value 4 at the start of the 4th iteration of the outer loop.
I'd want to filter each of these values from array2 as they become part of emptyArray so that they do not set off the if statement during the 6th and 8th iterations of the outer loop. I imagine that emptyArray = [2, 4] and array2 = [6, 8, 10] when the loops are finished.
Bottom line, I need emptyArray to collect the qualifying values and pass them back to var array2 for filtering as the loop processes. Remember this is a simplified version of the arrays, and underscore based solution would be very complicated for me to implement or for you to successfully suggest without much more detail.
My code:
var array = [1, 2, 3, 4, 1, 2, 3, 4];
var array2 = [2, 4, 6, 8, 10];
var emptyArray = [];
for (i = 0; i < array.length; i++){
var something = array[i];
var array2 = _.without(array2, emptyArray);
for (a = 0; a < array2.length; a++){
var value = array2[a];
if(something === value){
emptyArray.push(value);
break;
}
}
}
There are a few things wrong with your code, but the reason why you think that push isn't working is because you are overriding your array2 inside the loop.
The push never gets called because your for loop sees an empty array2 when you are doing var array2 = _.without(array2, emptyArray);
Basically var array2 = _.without(array2 /* this is empty, you just overrode it in this scope */, emptyArray); will always result in an empty array and your for loop will exit because length is array2.length === 0 from the start.
Also, you want to use _.difference instead of _.without
var array = [1, 2, 3, 4, 1, 2, 3, 4];
var array2 = [2, 4, 6, 8, 10];
var emptyArray = [];
for (var i = 0; i < array.length; i++) {
var something = array[i];
array2 = _.difference(array2, emptyArray);
for (var j = 0; j < array2.length; j++) {
var value = array2[j];
if (something === value) {
emptyArray.push(value);
break;
}
}
}
console.log("array2",array2);
console.log("emptyArray", emptyArray);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.5.0/lodash.js"></script>
array2 [6, 8, 10]
emptyArray [2, 4]
var array = [1, 2, 3, 4, 1, 2, 3, 4];
var array2 = [2, 4, 6, 8, 10];
var emptyArray = [];
for (var i = 0; i < array.length; i++) {
var something = array[i];
for (var j = 0; j < array2.length; j++) {
var value = array2[j];
if (something === value) {
array2 = _.without(array2, value);
break;
}
}
}

Javascript Array.push method issue

I have the following code:
function build_all_combinations(input_array){
array = [1,2,3]
limit = array.length - 1
combo = []
for(i = 0; i<= limit; i++){
splice_value = array.splice(0,1)
push_value = splice_value[0]
array.push(push_value)
console.log(array)
combo.push(array)
}
console.log(combo)
}
Which outputs:
[2, 3, 1]
[3, 1, 2]
[1, 2, 3]
[[1, 2, 3], [1, 2, 3], [1, 2, 3]]
The last line should be: [[2, 3, 1],[3, 1, 2],[1, 2, 3]]
I'm obviously not grokking something about the way the array is working. Each individual array is correct, but when I go to push them to the combo array, something is failing along the way. What is it?
Each time you are pushing the same array into the combo array; ie, all the references are pointing to the same instance in memory. So when you update one, you've in reality updated them all.
If you want separate references, you'll need to create separate arrays.
shift and slice are your friends here:
var array = [1,2,3];
var combo = []
for(var i = 0; i<array.length; i++){
array.push(array.shift()); // remove first element (shift) and add it to the end (push)
combo.push(array.slice()); // add a copy of the current array to combo
}
DEMO
jordan002 has given the explanation for this behaviour.
Here's the workaround.
array = [1,2,3]
limit = array.length - 1
combo = []
for(i = 0; i<= limit; i++){
splice_value = array.splice(0,1)
push_value = splice_value[0];
array.push(push_value);
console.log(array);
combo.push(array.concat([]));
}
console.log(combo);
You can store a copy in temp variable.
array = [1,2,3]
limit = array.length - 1
combo = []
for(i = 0; i<= limit; i++){
splice_value = array.splice(0,1)
push_value = splice_value[0];
array.push(push_value);
console.log(array);
var temp = array.slice();
combo.push(temp);
}
console.log(combo)
Reference

Categories

Resources