Reputation: 238
I am trying to get the smallest string out of every nested array in the following array object
let data = ["test string", ["abcd", "efj", ["hijklm", ["op"], "hijk", "hijklmn", ["op", "opq"]]]]
I have tried the code but it gives me stackoverflow error,Any help please
let data = ["test string", ["abcd", "efj", ["hijklm", ["op"], "hijk", "hijklmn", ["op", "opq"]]]]
let smallest = []
function getSmallest(data) {
data.forEach((ele, i) => {
if (typeof ele == "string") {
smallest.push(ele);
} else if (typeof ele == "object") {
// removing the array first
let _data = JSON.parse(JSON.stringify(data));
let only_array = _data.splice(i, 1);
getSmallest(only_array)
// now data contains only strings
//finding the smalles string from array
let small = _data.filter(v => typeof v === 'string')
.reduce((a, v) => a && a.length <= v.length ? a : v, '')
smallest.push(small);
}
});
}
getSmallest(data);
console.log(smallest)
Required result -Smallest in every array (nested one as well)
["test string", "efj", "hijk", "op", "op"]
Upvotes: 1
Views: 263
Reputation: 339786
This version works by accumulating the results into an array (initially empty) that is passed down through the recursive layers:
// (sup-optimal) helper function to split the array by type
// if you want optimal, use the underscore version
const partition = (a, pred) => [ a.filter(pred), a.filter(e => !pred(e)) ];
// helper function for reduce
const shorter = (a, b) => (a.length < b.length) ? a : b;
function getSmallest(data, result = []) {
// split the array into strings and subarrays
const [strings, sub] = partition(data, e => typeof e === 'string');
// add the shortest string, if any
if (strings.length) {
result.push(strings.reduce(shorter));
}
// recurse through sub-arrays, if any
if (sub.length) {
sub.forEach(e => getSmallest(e, result));
}
return result;
}
Upvotes: 0
Reputation: 14904
An solution with recursive function and reduce
let data = ["test string", ["abcd", "efj", ["hijklm", ["op"], "hijk", "hijklmn", ["op", "opq"]]]]
let result = [];
function getSmallestString(inp) {
let smallest = inp.reduce((a,v) => {
if(Array.isArray(v)) {
getSmallestString(v);
return a;
}
if(!a || v.length < a.length) return v;
return a;
}, null)
result.unshift(smallest);
}
getSmallestString(data);
console.log(result);
Upvotes: 0
Reputation: 1590
Just vanilla javascript
let data = [
"test string",
["abcd", "efj", ["hijklm", ["op"], "hijk", "hijklmn", ["op", "opq"]]],
];
let k = 0;
let result = [];
function smallestStringSolve(arr) {
let temp_arr = [];
let smallest_string_len = Infinity;
let smallest_string = "";
for (let i = 0; i < arr.length; i++) {
if (typeof arr[i] == "string") {
if (arr[i].length < smallest_string_len) {
smallest_string_len = arr[i].length;
smallest_string = arr[i];
}
}else if (Array.isArray(arr[i])){
temp_arr.push(arr[i]);
}
}
if(smallest_string)
result[k++] = smallest_string;
if (temp_arr.length){
for(let i=0; i<temp_arr.length; i++)
smallestStringSolve(temp_arr[i]);
}
return;
}
smallestStringSolve(data);
console.log(result);
Upvotes: 0
Reputation: 22474
You can use .reduce
, here is an example:
const data = ["test string", ["abcd", "efj", ["hijklm", ["op"], "hijk", "hijklmn", ["op", "opq"]]]]
const sortingWeight = (v) => Array.isArray(v) ? Infinity : v.length
const reducer = (acc, cur, i, arr) => {
if (Array.isArray(cur)) {
acc = [...acc, ...cur.reduce(reducer, [])];
} else if (i === 0) {
const smallestAtThisLevel = arr.sort((a, b) => {
a = sortingWeight(a);
b = sortingWeight(b);
return a - b;
})[0];
if (!Array.isArray(smallestAtThisLevel)) {
acc.push(smallestAtThisLevel);
}
}
return acc;
}
const result = data.reduce(reducer, []);
console.log(result);
Upvotes: 1
Reputation: 386550
You could take a recursive approach.
const
smallest = array => array
.reduce((r, value) => {
if (Array.isArray(value)) r.push(...smallest(value));
else if (!r[0].length || r[0][0].length > value.length) r[0][0] = value;
return r;
}, [[]])
.flat(),
data = ["test string", ["abcd", "efj", ["hijklm", ["op"], "hijk", "hijklmn", ["op", "opq"]]]],
result = smallest(data);
console.log(result);
Upvotes: 1
Reputation: 177
let data = ["test string", ["abcd", "efj", ["hijklm", ["op"], "hijk", "hijklmn", ["op", "opq"]]]]
const shorter = (left, right) => left.length <= right.length ? left : right;
const smallest = data.flat(Infinity).reduce(shorter)
console.log(smallest);
Upvotes: 0