Javascript list loop/recursion to create an object - javascript

I'm trying to create a function to process a list of numbers relating to depth using recursion or loops in JavaScript.
The following "input" needs to be processed into the "output", and it needs to work for arbitary lists.
One thing to note is that numbers increase by either 0 or 1 but may decrease by any amount.
var input = [0, 1, 2, 3, 1, 2, 0]
var output =
[ { number: 0, children:
[ { number: 1, children:
[ { number: 2, children:
[ { number: 3, children: [] } ]
}
]
}
, { number: 1, children:
[ { number: 2, children: [] } ]
}
]
}
, { number: 0, children: [] }
]
I worked it out myself, although it needs some refinement.
var example = [0, 1, 2, 2, 3, 1, 2, 0]
var tokens = []
var last = 0
const createJSON = (input, output) => {
if (input[0] === last) {
output.push({ num: input[0], children: [] })
createJSON(input.splice(1), output)
}
else if (input[0] > last) {
last = input[0]
output.push(createJSON(input, output[output.length-1].children))
}
else if (input[0] < last) {
var steps = input[0]
var tmp = tokens
while (steps > 0) {
tmp = tmp[tmp.length-1].children
steps--
}
tmp.push({ num: input[0], children: [] })
createJSON(input.splice(1), tmp)
}
}
createJSON(example, tokens)
console.log(tokens)

In fact, it's a very simple problem to solve...
var input = [0, 1, 2, 3, 1, 2, 0]
, output = []
, parents = [output]
;
for(el of input)
{
let nv = { number:el, children:[] }
parents[el].push( nv )
parents[++el] = nv.children // save the #ddress of children:[] for adding items on
}
console.log( output )
.as-console-wrapper { max-height: 100% !important; top: 0; }

Here's a functional solution based on recursion and Array.prototype.reduce:
const data = [0, 1, 2, 3, 1, 2, 0]
const last = xs => xs.length > 0 ? xs[xs.length - 1] : undefined
const lastD = (d, t, i = 0) => i > d ? t : lastD(d, last(t).children, i + 1)
const buildIt = xs => xs.reduce(
(a, x) =>((x === 0 ? a : lastD(x - 1, a)).push({ number: x, children: [] }), a),
[]
)
console.log(buildIt(data))
.as-console-wrapper { max-height: 100% !important; top: 0; }
Note: This solution does not depend on the mutation of additional variables for bookkeeping purposes.
Turns out the actual problem was significantly simpler to solve than my initial misinterpretation!

Related

Value change in 1 object changes in all objects in array

I have an array of objects. Each object has a key quantity and value. I want to duplicate each object in the array based on its quantity. Next, I want to manipulate only one of the duplicated object in the array. But on manipulating value of 1 object, value of all duplicated objects change. Here is my code:
let arr = [
{ id: 1, quantity: 3, value: 10 },
{ id: 2, quantity: 1, value: 5 },
{ id: 2, quantity: 5, value: 5 },
];
const newArr = [];
for (const a of arr) {
if (a.quantity > 1) {
let quantity = a.quantity;
a.quantity = 1;
while (quantity--) {
newArr.push(a);
}
}
}
arr = newArr;
arr[0].value = 1;
When I changed the value of arr[0] to 1, value field of arr[1] and arr[2] also changed to 1.
I have tried copying the object using spread operator and JSON.parse(JSON.parse()), but none has worked.
Because newArr.push(a) .a push to newArr ref to element of arr
You can edit same as :
let arr = [
{ id: 1, quantity: 3, value: 10 },
{ id: 2, quantity: 1, value: 5 },
{ id: 2, quantity: 5, value: 5 },
]
const newArr = []
for (const a of arr) {
if (a.quantity > 1) {
let quantity = a.quantity;
a.quantity = 1;
while (quantity--) {
newArr.push({...a})
}
}
}
arr = [...newArr]
arr[0].value = 1
console.log(arr)
// example for Memory Management
let a = { id: 1, quantity: 3, value: 10 }
let b = { id: 1, quantity: 3, value: 10 }
let c = arr[0]
let d = {...arr[0]}
console.log(a === arr[0]) // false : different allocates memory for contain value
console.log(a === b) // false : different allocates memory for contain value
console.log(c === arr[0]) // true : refer to a memory
console.log(d === arr[0]) // false : different allocates memory for contain value

Dynamically adding more values in Javascript

How can I dynamically add more values in the sets defined as follows in Javascript:
var data1 = [
{ name: 'S1', elems: [0, 1, 2] },
{ name: 'S2', elems: [1, 2, 3] },
{ name: 'S3', elems: [0, 2, 4] },
];
What I want to do is similar to the following:
(key, value) = read_a_row_from_table_of_values;
if (key is present in data1) // could be by iterating all the keys in data
{
data1[key][elems].push(value); // this is the point of concern (how to push values)
}
As I am feeding this data to another tool (UpSet), so this data structure (in the form of name and elems) has to be followed. Details about that can be found here.
If you're only ever adding 1 or 2 items (i.e. such that O(n) insert time is acceptable) then this solution (based on #mplungjan's now-deleted comment) should work for you:
var data1 = [
{ name: 'S1', elems: [0, 1, 2] },
{ name: 'S2', elems: [1, 2, 3] },
{ name: 'S3', elems: [0, 2, 4] },
];
function add( data1, name, value ) {
const exists = data1.find( e => e.name === name );
if( exists ) {
exists.elems.push( value );
}
else {
data1.push( { name, elems: [value] } );
}
}
add( data1, 'S4', 1 );
add( data1, 'S3', 2 );
add( data1, 'S5', 3 );
If you'll be performing mass operations on data1 then you should convert it to a Map first (note that Array.prototype.map and Map<K,V> are completely different things):
function convertData1ToMap( data1 ) {
const m = new Map();
for( const e of data1 ) {
m.set( e.name, e.elems );
}
return m;
}
function convertMapToData1( m ) {
const arr = [];
for( const k of map.keys() ) {
const elems = map.get( k );
arr.push( { name: k, elems } );
}
return arr;
}
//
const m = convertData1ToMap( data1 );
// Mass insert:
for( let i = 4; i < 10 * 1000; i++ ) {
const name = 'S' + i.toString();
if( m.has( name ) ) {
m.get( name ).push( i );
}
else {
m.set( name, [i]);
}
}
// Recreate `data1`:
data1 = convertMapToData1( m );
Entries and Find will work
Basically
data1.find(elem => elem.name===key).elems.push(value)
We can alas not do a oneliner if the newValues may contain a key not in the data1 array
const data1 = [
{ name: 'S1', elems: [0, 1, 2] },
{ name: 'S2', elems: [1, 2, 3] },
{ name: 'S3', elems: [0, 2, 4] },
];
const newValues = {"S1": 4,"S2":5, "S6": 6 }
Object.entries(newValues)
.forEach(([key, value]) => {
const found = data1.find(elem => elem.name === key);
if (found) found.elems.push(value);
});
console.log(data1);
If you want to merge, you need to add missing keys
const data1 = [
{ name: 'S1', elems: [0, 1, 2] },
{ name: 'S2', elems: [1, 2, 3] },
{ name: 'S3', elems: [0, 2, 4] },
];
const newValues = {"S1": 4,"S2":5, "S6": 6 }
Object.entries(newValues)
.forEach(([key, value]) => {
const found = data1.find(elem => elem.name === key);
if (found) found.elems.push(value);
else data1.push({name:key,elems: [value]});
})
console.log(data1);

Is there a better way of writing a function like this

The function below takes two arguments and returns an array of objects. Each object should be returned in descending order in reference to the availableBagSizes array.
I gave two examples, I want to know if there is a better solution to achieving the same output and why my solution is bad.
I need help with the third example it's not returning as expected.
function getBagCounts(clientOrders, availableBagSizes) {
// TODO: remove this hard-coded solution for test scenario
// clientOrders === [9]
// sorting the availablebag size in descending order
const newAvailableBag = availableBagSizes.sort((a, b) => b - a);
const result = [];
let newRemainder;
for (let index = 0; index < clientOrders.length; index++) {
const clientOrder = clientOrders[index];
// set the newremainder variable to clientOrder for the first loop
newRemainder = index === 0 ? clientOrder : newRemainder;
for (let j = 0; j < availableBagSizes.length; j++) {
const bagSize = newAvailableBag[j];
const count_result = Math.floor(newRemainder / bagSize);
newRemainder = newRemainder % bagSize;
const obj = {};
if (newRemainder > bagSize) {
result.push({ size: bagSize, count: 0 });
continue;
}
// checking if it is the last item in the bagSizes
if (j + 1 === availableBagSizes.length) {
// setting the newreaminder to the next number of client order
newRemainder = clientOrders[index + 1];
}
result.push({ size: bagSize, count: count_result });
}
}
return result;
}
// first example
const clientOrders = [9];
const availableBagSizes = [1, 2, 4];
const expectedoutput = [
{ size: 4, count: 2 },
{ size: 2, count: 0 },
{ size: 1, count: 1 }
];
// second example
const clientOrders = [5, 12, 12];
const availableBagSizes = [1, 2, 4];
const expectedoutput = [
{ size: 4, count: 1 },
{ size: 2, count: 0 },
{ size: 1, count: 1 },
{ size: 4, count: 3 },
{ size: 2, count: 0 },
{ size: 1, count: 0 },
{ size: 4, count: 2 },
{ size: 2, count: 1 },
{ size: 1, count: 0 }
];
// third example
const clientOrders = [4.5];
const availableBagSizes = [1, 2, 4];
const expectedoutput = [
{ size: 4, count: 1 },
{ size: 2, count: 0 },
{ size: 1, count: 0.5 }
];
It looks good to me.
You should think about performance and check of parameters if you want a good code.
if (!Array.isArray(clientOrders) || !Array.isArray(availableBagSizes)) {
return null;
}
Also you should try to use forEarch loop which is faster in performance
Making a push is slow, better make a .map((element,index)=>{return null})
It really depends how you manage your data, but I would say first loop is a forEach, and second loop you make a map. Because whatever the case in your second loop, all the time you make a push there would be no null or undefined return in your mapped array.

How to keep checking array until certain condition is met

I have two arrays idarray and array and want to find item_tosearch in idarray. Then using the found index loop forward through idarray until an element is found that is not -1. Then use that index to retreive the value from array.
From what I know, if you want to keep checking you can use any sort of iteration either for or while or foreach in this case, I've got 2 arrays. First is for idarray and second is for array. I've managed to check what is the next data and if the data has reached the final value. I also able to get what I want which is the next data as long as the id wasn't -1.
What I've tried:
var item_tosearch = 0;
var idarray = [-1, 2, -1, 4, -1]
var array = [3, 2, 1, 0, 7];
var index = array.indexOf(item_tosearch);
if (index > -1) {
var res = array.slice(index);
}
if (res != undefined) {
for (let i = 0; i < res.length; i++) {
if (res[i + 1] != undefined) {
if (idarray[index + 1] == -1) {
if (res[i + 2] != undefined) {
console.log("Next = " + res[i + 2]);
break;
} else {
console.log("Final index");
break;
}
} else {
console.log("Next = " + res[i + 1]);
break;
}
} else {
console.log("Final index");
}
}
} else {
console.log('data not found');
}
My question is, is there any way I could've improved the method?
Any advice is apreciated.
Clarification:
If I have the following:
idarray = [-1, 2, -1, 4, 1];
array = [3, 2, 1, 0, 7];
What I would like to have is if I put 2 on item_tosearch as value, I'm expecting to have: 0 as the returned value since it was the next item without -1 in the id.
Another case, if I had:
idarray = [-1, 2, -1, -1, 1];
array = [3, 2, 1, 0, 7];
And if I put 2 on item_tosearch as value, I'm expecting to have: 7 as the returned value since it was the next item without -1 in the id.
But if idarray was = [-1, 2, -1, -1, -1] with the same 2 on item_tosearch as value. I expect "final index" to be returned. Since no more item without -1 as the id.
I've tried another iteration to fetch but doesn't seem to get what I want:
var item_tosearch = 2;
var idarray = [-1, 2, -1, -1, -1]
var array = [3, 2, 1, 0, 7];
var index = array.indexOf(item_tosearch);
if (index > -1) {
var res = array.slice(index);
}
if (res != undefined) {
for (let i = 0; i < res.length; i++) {
if (res[i + 1] != undefined) {
if (idarray[index + 1] == -1) {
for (let j = i + 1; j < res.length - i; j++) {
if (res[j + 1] != undefined) { // fetch if still got data with id != -1
console.log("Next = " + res[j + 1]); // should show next item without -1 in id
break;
} else {
console.log("Final index"); // reach end of array
break;
}
}
} else {
console.log("Next = " + res[i + 1]); // should show next item without -1 in id
break;
}
} else {
console.log("Final index"); // reach end of array
}
}
} else {
console.log('data not found');
}
If I understand your question good enough you're looking for something like this. Even if this isn't exactly the solution you want you might be able to get some inspiration from it.
This solution starts by finding the index of the element to search in idarray. If it can't be found return undefined.
Next start looping from 1 index higher until the end of the idarray. If an element is found that is not -1 return the element on the current index from array.
If nothing is found undefined is returned.
var idarray, array;
function giveThisABetterName(item_tosearch, idarray, array) {
var index = idarray.indexOf(item_tosearch);
if (index === -1) return; // data not found
for (index += 1; index < idarray.length; ++index) {
if (idarray[index] !== -1) return array[index];
}
// reach end of array
}
idarray = [-1, 2, -1, 4, 1];
array = [ 3, 2, 1, 0, 7];
console.log(giveThisABetterName(2, idarray, array));
idarray = [-1, 2, -1, -1, 1];
array = [ 3, 2, 1, 0, 7];
console.log(giveThisABetterName(2, idarray, array));
idarray = [-1, 2, -1, -1, 1];
array = [ 3, 2, 1, 0, 7];
console.log(giveThisABetterName(9, idarray, array));
Ok, I think I kind of understand the logic, but I'm not sure.
Is the question: I want to check if any of the ids following the id corresponding with my value, is not -1 ?
Hope I understood the logic correctly.
If you have no use for reusable functions, or don't care about structure, you can write this very short as well:
var pos = 0;
var idarray = [ -1, 2, -1, 4, -1 ];
var array = [ 3, 2, 1, 0, 7 ];
var get_result = ( array, idarray, pos, ex ) => {
const offset = array.indexOf( pos ) + 1;
return idarray
.slice( offset )
.reduce(( result, id, index ) => {
if ( result === "final index" && id !== -1 ) result = array[ index + offset ];
return result;
}, "final index" );
};
// example 1:
const ex1_search_value = 0; // pos
const ex1_ids = [ -1, 2, -1, 4, -1 ]; // idarray
const ex1_values = [3, 2, 1, 0, 7]; // array
// expect "final index", since our range will only contain the last id, which is -1
const result1 = get_result( ex1_values, ex1_ids, ex1_search_value );
console.log( `expect final index, ${ result1 }` );
// example2:
const ex2_search_value = 2;
const ex2_ids = [ -1, 2, -1, -1, -1 ];
const ex2_values = [3, 2, 1, 0, 7];
// expect "final index", since our range is the last two items, both with id -1
const result2 = get_result( ex2_values, ex2_ids, ex2_search_value );
console.log( `expect final index, ${ result2 }` );
// example3:
const ex3_search_value = 2;
const ex3_ids = [ -1, 2, -1, -1, -1, -1, -1, -1, -1, 3, -1, 2, -1, -1 ];
const ex3_values = [ 3, 2, 1, 0, 7, 4, 9, 14, 74, 8, 45, 14, 17, 84 ];
// expect { id: 3, value: 8 }
const result3 = get_result( ex3_values, ex3_ids, ex3_search_value );
console.log( `expect 8, ${ result3 }` );
// example4:
const ex4_search_value = 2;
const ex4_ids = [-1, 2, -1, 4, 1];
const ex4_values = [ 3, 2, 1, 0, 7];
// expect { id: 4, value: 0 }
const result4 = get_result( ex4_values, ex4_ids, ex4_search_value );
console.log( `expect 0, ${ result4 }` );
// example5:
const ex5_search_value = 2;
const ex5_ids = [-1, 2, -1, -1, 1];
const ex5_values = [ 3, 2, 1, 0, 7];
// expect { id: 1, value: 7 }
const result5 = get_result( ex5_values, ex5_ids, ex5_search_value );
console.log( `expect 7, ${ result5 }` );
// example6:
const ex6_search_value = 2;
const ex6_ids = [-1, 2, -1, -1, -1];
const ex6_values = [ 3, 2, 1, 0, 7];
// expect "final index"
const result6 = get_result( ex6_values, ex6_ids, ex6_search_value );
console.log( `expect final index, ${ result6 }` );
My other approach here is to merge the arrays into one array containing objects, so that we do not have to check for undefined values, while still being able to use array methods instead of plain loops. This would help if you have to use the id/value combinations alot in the code past this point. The functions are just there to make everything reusable.
// Create an object from the id and value combinations.
const create_collection = ( ids, values ) => {
return ids.map(( id, index ) => ({
id,
value: values[ index ]
}));
};
const has_valid_descendants = ( collection, search_value ) => {
// Find the index of the first item that has our requested value.
const search_index = collection.findIndex( item => item.value === search_value );
// Slice the relevant part from the collection.
// Since we will only look at records past the item ahving the search_value, we mights well only slice the relevant parts.
const collection_in_range = collection.slice( search_index + 1 );
// Find the first item in range has an id that is not -1.
return collection_in_range.find( item => item.id !== -1 ) || 'final index';
};
// example 1:
const ex1_search_value = 0; // pos
const ex1_ids = [ -1, 2, -1, 4, -1 ]; // idarray
const ex1_values = [3, 2, 1, 0, 7]; // array
// Collection should be: [{ id: -1, value: 3 },{ id: 2, value: 2 },{ id: -1, value: 1 },{ id: 4, value: 0 },{ id: -1, value: 7 }];
const ex1_collection = create_collection( ex1_ids, ex1_values );
console.log( ex1_collection );
// Is there a valid next item?
// expect "final index", since our range will only contain the last id, which is -1
const ex1_result = has_valid_descendants( ex1_collection, ex1_search_value );
console.log( 'expect 1: "final index"' );
console.log( `example 1: ${ JSON.stringify( ex1_result ) }` );
// example2:
const ex2_search_value = 2;
const ex2_ids = [ -1, 2, -1, -1, -1 ];
const ex2_values = [3, 2, 1, 0, 7];
// expect "final index", since our range is the last two items, both with id -1
const ex2_result = has_valid_descendants(
create_collection( ex2_ids, ex2_values ),
ex2_search_value
);
console.log( 'expect 2: "final index"' );
console.log( `example 2: ${ JSON.stringify( ex2_result ) }` );
// example3:
// We add a bunch of other values and ids.
// This proves it will work with longer arrays as well
// and that the result is the first item without the id -1
const ex3_search_value = 2;
const ex3_ids = [ -1, 2, -1, -1, -1, -1, -1, -1, -1, 3, -1, 2, -1, -1 ];
const ex3_values = [ 3, 2, 1, 0, 7, 4, 9, 14, 74, 8, 45, 14, 17, 84 ];
// expect { id: 3, value: 8 }
const ex3_result = has_valid_descendants(
create_collection( ex3_ids, ex3_values ),
ex3_search_value
);
console.log( 'expect 3: { id: 3, value: 8 }"' );
console.log( `example 3: ${ JSON.stringify( ex3_result ) }` );
// example4:
// Note: I've added || 'final index'; to the has_valid_descendants() function.
const ex4_search_value = 2;
const ex4_ids = [-1, 2, -1, 4, 1];
const ex4_values = [3, 2, 1, 0, 7];
// expect { id: 4, value: 0 }
const ex4_result = has_valid_descendants(
create_collection( ex4_ids, ex4_values ),
ex4_search_value
);
console.log( 'expect 4: { id: 4, value: 0 }' );
console.log( `example 4: ${ JSON.stringify( ex4_result ) }` );
// example5:
// Note: I've added || 'final index'; to the has_valid_descendants() function.
const ex5_search_value = 2;
const ex5_ids = [-1, 2, -1, -1, 1];
const ex5_values = [3, 2, 1, 0, 7];
// expect { id: 1, value: 7 }
const ex5_result = has_valid_descendants(
create_collection( ex5_ids, ex5_values ),
ex5_search_value
);
console.log( 'expect 5: { id: 1, value: 7 }' );
console.log( `example 5: ${ JSON.stringify( ex5_result ) }` );
// example6:
// Note: I've added || 'final index'; to the has_valid_descendants() function.
const ex6_search_value = 2;
const ex6_ids = [-1, 2, -1, -1, -1];
const ex6_values = [3, 2, 1, 0, 7];
// expect "final index"
const ex6_result = has_valid_descendants(
create_collection( ex6_ids, ex6_values ),
ex6_search_value
);
console.log( 'expect 6: "final index"' );
console.log( `example 6: ${ JSON.stringify( ex6_result ) }` );

Flattening nested array in JavaScript

I have a horrible looking array which looks like this:
EDIT:
array = [
{
Letters: [{ Letter: 'A' }, { Letter: 'B' }, { Letter: 'C' }],
Numbers: [{ Number: '1' }, { Number: '2' }, { Number: '3' }]
},
null,
{
Letters: [{ Letter: 'D' }, { Letter: 'E' }, { Letter: 'F' }, { Letter: 'G' }, { Letter: 'H' }],
Numbers: [{ Number: '4' }, { Number: '5' }, { Number: '6' }, { Number: '7' }]
}
];
And want the array to look like this:
flattenedArray = [a,b,c,1,2,3,d,e,f,g,h,4,5,6,7]
Unfortunately I cannot change the original formatting because that is the form received when merging two API responses that I am getting.
I have tried using:
var flattenedArray = [].concat.apply([], array);
But it just presents the array in the same format it was entered in.
I was wondering if anybody had any advice?
EDIT:
I have tried implementing the suggestions given - thank you so much for your help. It seems it is a problem with the format of the list - unfortunately using the chrome console which is in a 'tree' format I cannot see the direct structure of the array output.
Thank you for all your help!
EDIT 2: See above for the actual array, thank you for showing me how to see this!
If you have lodash, you can use:
_.flattenDeep(array)
You can also checkout their source code for ides on how to implement yourself if you prefer.
Edit for the new request of nested arrays/objects and the flattening, you could use a combined approach with testing for the type of an element.
var array = [{ Letters: [{ Letter: 'A' }, { Letter: 'B' }, { Letter: 'C' }], Numbers: [{ Number: '1' }, { Number: '2' }, { Number: '3' }] }, null, { Letters: [{ Letter: 'D' }, { Letter: 'E' }, { Letter: 'F' }, { Letter: 'G' }, { Letter: 'H' }], Numbers: [{ Number: '4' }, { Number: '5' }, { Number: '6' }, { Number: '7' }] }],
result = array.reduce(function iter(r, a) {
if (a === null) {
return r;
}
if (Array.isArray(a)) {
return a.reduce(iter, r);
}
if (typeof a === 'object') {
return Object.keys(a).map(k => a[k]).reduce(iter, r);
}
return r.concat(a);
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Old request and the immortal question how to flat a nested array.
var flat = (r, a) => Array.isArray(a) ? a.reduce(flat, r) : r.concat(a),
inputArray = array = [[['a', 'b', 'c'], [1, 2, 3]], [], [['d', 'e', 'f', 'g', 'h'], [4, 5, 6, 7]]],
outputArray = inputArray.reduce(flat, []);
console.log(outputArray);
You can create recursive function using forEach() that will return new array.
var array = [[['a','b','c'],[1,2,3]],[],[['d','e','f','g','h'],[4,5,6,7]]]
function flat(data) {
var r = []
data.forEach(e => Array.isArray(e) ? r = r.concat(flat(e)) : r.push(e));
return r;
}
console.log(flat(array))
You can also use reduce() instead of forEach()
var array = [[['a','b','c'],[1,2,3]],[],[['d','e','f','g','h'],[4,5,6,7]]]
function flat(data) {
return data.reduce((r, e) => Array.isArray(e) ? r = r.concat(flat(e)) : r.push(e) && r, [])
}
console.log(flat(array))
As #Bergi suggested you can use reduce() like this.
data.reduce((r, e) => r.concat(Array.isArray(e) ? flat(e) : [e]), [])
It's nice to use a recursive function for such cases:
arr = [[['a','b','c'],[1,2,3]],[],[['d','e','f','g','h'],[4,5,6,7]]];
function flatten(arr) {
var result = [];
for (var i = 0, len = arr.length; i < len; i++) {
result = result.concat(Array.isArray(arr[i])? flatten(arr[i]) : [arr[i]]);
}
return result;
}
console.log(flatten(arr));
You could try the flatten function in Ramda.
R.flatten([1, 2, [3, 4], 5, [6, [7, 8, [9, [10, 11], 12]]]]);
//=> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
Your Array format is not correct, you are missing commas(,). This is correct array.
var array = [[['a','b','c'],[1,2,3]],[],[['d','e','f','g','h'],[4,5,6,7]]];
var array = [[['a','b','c'],[1,2,3]],[],[['d','e','f','g','h'],[4,5,6,7]]];
var result = flatten(array);
function flatten(array) {
var flat = [];
if(array !== undefined){
var flat = [];
for (var i = 0; i < arguments.length; i++) {
if (arguments[i] instanceof Array) {
flat = flat.concat(flatten.apply(null, arguments[i]));
} else {
flat.push(arguments[i]);
}
}
}
return flat;
}
console.log(result);
No one thought of splicing in-place?
function flatten(array){
for (var i = 0; i < array.length; i++) {
if(array[i] instanceof Array){
array.splice.apply(array,[i,1].concat(array[i]));
i--;
}
};
return array;
}
One iteration, no recursion.
Implement flatten function using recursion and spread operator.
const a = [1,[2,[3,4],[5]],6];
const flatten = (arr) => {
const res = []
for(let i=0;i<arr.length;i++) {
if(!Array.isArray(arr[i])) res.push(arr[i]);
else res.push(...flatten(arr[i]));
}
return res;
}
console.log(flatten(a));
function steamrollArray(arr) {
var tmp = [];
arr.forEach(function(val){
if(Array.isArray(val))
tmp = tmp.concat(steamrollArray(val));
else
tmp.push(val);
});
console.log(tmp);
return tmp;
}
steamrollArray([1, [2], [3, [[4]]]]);
let arr = [1,2,[3,4]]
/* let newarr = arr.flat(); */
let newarr = Object.values(arr);
let arr2 = []
for(let val of Object.values(arr)) {
if(!Array.isArray(val)){
console.log(val)
arr2.push(val)
}
for ( let val2 of Object.values(val)){
arr2.push(val2)
}
}
console.log(arr2)

Categories

Resources