1

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"]
9
  • please add the wanted result. what happen to more than one shortest string? Commented Aug 25, 2020 at 8:51
  • Why is smallest an array? Isn't there just one smallest string? Commented Aug 25, 2020 at 8:51
  • What is your goal with let _data = JSON.parse(JSON.stringify(data));? (JSON.parse(JSON.stringify(x)) is an anti-pattern 99.999999% of the time.) Commented Aug 25, 2020 at 8:52
  • You're using a lot of over-complex things in that code. Just use simple for or for-of loops. Commented Aug 25, 2020 at 8:53
  • 1
    for those suggesting flattening the array - the OP does appear to want a flat array result but the values are the shortest string found within each level of nested arrays. Commented Aug 25, 2020 at 8:57

6 Answers 6

1

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);

Sign up to request clarification or add additional context in comments.

Comments

1

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);

Comments

0

    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);

Comments

0

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);

Comments

0

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);

Comments

0

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;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.