gANDALF
gANDALF

Reputation: 238

Get smallest string out of the array with nested arrays

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

Answers (6)

Alnitak
Alnitak

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

Ilijanovic
Ilijanovic

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

namar sood
namar sood

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

Titus
Titus

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

Nina Scholz
Nina Scholz

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

Akash Vishwakarma
Akash Vishwakarma

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

Related Questions