Concisely mapping 2 columns from 2D array to key:value pairs - javascript

In this example snippet of code, I selectively convert 2 columns from my 2D array into an object. The 1st column represents the keys, the 2nd represents the values.
I feel like there is a more concise way of codifying this idea without so many lines of code.
var my2dArray = [ ['a',2], ['b',3], ['c',4] ];
var keys = [];
var values = [];
var myObj = {};
for(var row = 1; row < my2dArray.length; row++) {
keys[row] = my2dArray[row][0];
values[row] = my2dArray[row][1];
myObj[keys[row]] = values[row];
}
console.log(prod_compare); // outputs object
In reality, I have a 4 column array. Don't mind the simplicity of my2dArray. Is there a way to select these two columns for mapping to an object without having to declare 2 temporary arrays?

Your code is fundamentally OK, but it can be more concise without being obfuscated:
var my2dArray = [ ['a',2], ['b',3], ['c',4] ];
var myObj = {};
for (var i=0, iLen=my2dArray.length; i<iLen; i++) {
myObj[my2dArray[i][0]] = my2dArray[i][1];
}

This may convert [['a', 1, 2, 3], ['b', 1, 2, 3]] to {a: [1, 2, 3], b: [1, 2, 3]}.
for(var row = 0; row < my2dArray.length; row++) {
keys[row] = my2dArray[row][0];
values[row] = my2dArray[row].slice(1);
myObj[keys[row]] = values[row];
}

Related

How to generate an array filled with a few different values?

I want to generate the following array:
[3, 3, 3, 3, 4, 4, 5, 5, 5]
there are 3 different values that should repeat m, n, and k times. What is the easiest way to do that?
If I do Array(m + n + k).fill(...).fill(...).fill(...) the start and end points in later fill calls look not very straightforward.
Generate the arrays separately and then combine them into one final array
[
...Array(4).fill(3),
...Array(2).fill(4),
...Array(3).fill(5)
]
Create an array of values, and an array of repeat. Iterate the values with Array.map(), and return a new array filled with the values. Flatten by spreading into Array.concat():
const values = [3, 4, 5];
const repeat = [4, 2, 3];
const arr = [].concat(...values.map((v, i) => new Array(repeat[i]).fill(v)));
console.log(arr);
var arrValues = [3,4,5];
var arrRepeats = [4,2,3];
var arr = [];
for(var i =0; i< arrRepeats.length;i++){
arr.push(Array(arrRepeats[i]).fill(arrValues[i]));
}
console.log(arr)
Or
var arrValues = [3,5,4];
var arrRepeats = [4,2,3];
let arr = [];
for(var i =0; i< arrRepeats.length; i++){
for(var j=0; j<arrRepeats[i];j++){
arr.push(arrValues[i]);
}
}
console.log(arr)
Or you can do that if you wanna generate arrays and combine them
var arrValues = [3,5,4];
var arrRepeats = [4,2,3]; // m, n, k
var mainArr = [];
for(var i =0; i< arrRepeats.length; i++){
var arr = [];
for(var j =0; j < arrRepeats[i]; j++){
arr.push(j);
arr.fill(arrValues[i]);
}
mainArr.push(arr);
}
console.log(mainArr)

Output arrays in object in Javascript for spreadsheet

This is my code.
function order() {
//declare things
var order = [3, 2, 1, 0]
var testOne = [2, 3, 7, 4]
var testTwo = ["c", "b", "a", "d"]
//sort by order
var collatedArray = [];
for (var i = 0; i < order.length; i++)
{
index = order[i];
var collated =
{
test1 : testOne[index],
test2 : testTwo[index]
}
collatedArray.push(collated);
}
//Create output
var output = [];
for (i=0; i<collatedArray.length; i++)
{
output[i] = collatedArray[i].test1
}
return output
}
The output currently is only collatedArray[i].test1, which gives:
4, 7, 3, 2
If I change output[i] = collatedArray[i].test1 to test2, I get:
d, a, b, c
I just want to output the whole collatedArray (test1 and test2) so that I get:
4, 7, 3, 2
d, a, b, c
without the need for output variable, or converting back to arrays. The info is all there I just can't figure out how to get it out. Very new to coding, just not understanding what to do here :(
Thanks
Adjust output to an array containing two arrays; within last for loop populate each array within output with values at collatedArray[0][i].test1 and collatedArray[1][i].test2
// Create output
var output = [[], []];
for (i=0; i<collatedArray.length; i++)
{
output[0][i] = collatedArray[i].test1;
output[1][i] = collatedArray[i].test2;
}
function order() {
//declare things
var order = [3, 2, 1, 0]
var testOne = [2, 3, 7, 4]
var testTwo = ["c", "b", "a", "d"]
//sort by order
var collatedArray = [];
for (var i = 0; i < order.length; i++) {
index = order[i];
var collated = {
test1: testOne[index],
test2: testTwo[index]
}
collatedArray.push(collated);
}
//Create output
var output = [
[],
[]
];
for (i = 0; i < collatedArray.length; i++) {
output[0][i] = collatedArray[i].test1;
output[1][i] = collatedArray[i].test2;
}
return output
}
console.log(order())
There are several ways that you can do this, including storing each testNumber (testOne, testTwo, etc) in an object consisting of properties. Learn how objects work and you should, having observed your code here, easily be able to figure out how to loop through each property (which in your case will be arrays) of said Object to print out what you're looking for. If you can't figure it out, there are plenty of Stack Overflow Q&A's that cover this phenomenally well.
But for now, here is a simple alternative: an array of arrays.
https://jsfiddle.net/6r3hv3aq/7/
var testOne = [2,3,7,4];
var testTwo = ["c","b","a","d"];
var test = [testOne,testTwo];
for (var i = 0; i <= test.length-1; i++) {
console.log(test[i]);
}
Which will output exactly what you asked for:
[2, 3, 7, 4]
["c", "b", "a", "d"]
Note: When you click the jsfiddle link provided, you may have to refresh the page to see the appropriate results loaded into the console. Alternatively, leave the console open when you migrate to the link.
Since you're wanting this for a spreadsheet I am assuming you want a CSV output string that you can import into a spreadsheet program.
function row(source, sequence) {
var temp = new Array(sequence.length);
for (var i = 0; i < sequence.length; i++)
temp[i] = source[sequence[i]];
return temp.join(",")
}
function order() {
//declare things
var sequence = [3, 2, 1, 0];
var testOne = [2, 3, 7, 4];
var testTwo = ["c", "b", "a", "d"];
var rows = [];
rows.push(row(testOne, sequence));
rows.push(row(testTwo, sequence));
return rows.join("\r\n");
}
Here's a plunkr

Looping through an object and a nested for loop that loops through array

I am looping through an object and then upon each object I am comparing it to the items in my array in hopes to then push the objects that are not the same into my ItemsNotInObject array. Hopefully someone can shine some light on this for me. Thank you in advance.
var obj = {a:1, a:2, a:3};
var array = [1, 4, 2, 5, 6];
var ItemsNotInObject = [];
for (var prop in obj) {
for(var i = 0, al = array.length; i < al; i++){
if( obj[prop].a !== array[i] ){
ItemsNotInObject.push(array[i]);
}
}
}
console.log(ItemsNotInObject);
//output of array: 1 , 4 , 2 , 5, 6
//output desired is: 4 , 5 , 6
Your object has duplicate keys. This is not a valid JSON object. Make them unique
Do not access the object value like obj[prop].a, obj[prop] is a
Clone the original array.
Use indexOf() to check if the array contains the object property or not.
If it does, remove it from the cloned array.
var obj = {
a: 1,
b: 2,
c: 3
};
var array = [1, 4, 2, 5, 6];
var ItemsNotInObject = array.slice(); //clone the array
for (var prop in obj) {
if (array.indexOf(obj[prop]) != -1) {
for (var i = 0; i < ItemsNotInObject.length; i++) {
if (ItemsNotInObject[i] == obj[prop]) {
ItemsNotInObject.splice(i, 1); //now simply remove it because it exists
}
}
}
}
console.log(ItemsNotInObject);
If you can make your obj variable an array, you can do it this way;
var obj = [1, 2, 3];
var array = [1, 4, 2, 5, 6];
var ItemsNotInObject = [];
for(i in array){
if( obj.indexOf(array[i]) < 0) ItemsNotInObject.push(array[i]);
}
console.log(ItemsNotInObject);
if the obj variable needs to be json object please provide the proper form of it so i can change the code according to that.

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