0

I am going around in circles and struggling to find a solution; any education/guidance would really help me.

I may have a lot of arrays which I am doing string manipulation on.

I created a helpful debug function, to help me print the length of the elements in the arrays; post string manipulation.

This is the single array function, its working; however I'd like to use rest operators, as I'd like to feed it alot of arrays as parameters:

let arr1 = ["one", "two", "three"];
let arr2 = ["four", "five", "six"];
function debug_qty(arr) {
    let post_arr_filter = arr.map(function(word) {
        return `${word.length}`;
    });
    return post_arr_filter;
};

I have tried the below - but it only prints the first array, and when I append .length, I get 3, instead of 3,3,5 (the length of the individual strings).

let arr1 = ["one", "two", "three"];
let arr2 = ["four", "five", "six"];

function check_length(...args) {
    for (let arrs in args) {
        return args[arrs].length;
    };
};

My next attempt - this seems to find the two array lengths(i think), again not the child elements.

function calc_arr(...args) {
    let result = args.map(function(nums) {
        return nums.length;
    });
    return result;
}

I am going around in circles, so any mentoring would be most helpful. :)

dimButTries
  • 661
  • 7
  • 15
  • have you tried `let arr of args` instead of `let arr in args`? – Jhecht Dec 15 '19 at 02:06
  • Welcome to SO! Please show how you are calling these functions. If you are passing the whole array in without spreading, then you're calling the function incorrectly. Also, use `camelCase` for JS. – ggorlen Dec 15 '19 at 02:09

2 Answers2

1

The issue with your for...in approach is that you are returning inside your loop (also note that you should really only use for...in for iterating object properties, not array indexes). The return causes your function to exit and subsequently end the loop.

The issue with your last code snippet is that you're treating num as a single number, however, num is actually an array. When you do ...args args becomes an array of all the parameters you pass it. If you pass "one" and "two" args would be ["one", "two"]. If you pass ["one", "two"], ["three", "four"], args would then be an array of arrays [["one", "two"], ["three", "four"]]. For your .map() function to work, you really want the array you're working on to look like ["one", "two", "three", "four"], with all the elements in the one array. To get the array in this form you can use .flat(), or, since you're using .map():

function calc_arr(...args) {
  let result = args.flat().map(function(nums) {
    return nums.length;
  });
  return result;
}

let arr1 = ["one", "two", "three"];
let arr2 = ["four", "five", "six"];
console.log(calc_arr(arr1, arr2));

Alternatively, you could use .flatMap(), which flattens the array returned by the callback function into one larger array. This means the callback function of .flatMap() would need to return an array of counts:

function calc_arr(...args) {
  return args.flatMap(arr => arr.map(str => str.length));
}

let arr1 = ["one", "two", "three"];
let arr2 = ["four", "five", "six"];
console.log(calc_arr(arr1, arr2));

If you want an array of arrays, you can use Array.from with a mapping function:

const calc_arr = (...args) =>
  Array.from(args, arr => arr.map(({length}) => length));

const arr1 = ["one", "two", "three"];
const arr2 = ["four", "five", "six"];
console.log(calc_arr(arr1, arr2));
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
  • Thank you! I've learnt a new function "flat" through your stewardship, merging the arrays would have done the job and your snippet works. However, some of my arrays (post string manipulation) are 300+ in length. So the delineation in the arrays is quite helpful. – dimButTries Dec 15 '19 at 02:32
  • @NotAVeryGoodDeveloper so you actually want an array of arrays as your output? – Nick Parsons Dec 15 '19 at 02:40
  • 1
    Hey good evening - yes that is correct! array.from is another great function, I would have missed, thank you!! – dimButTries Dec 15 '19 at 03:04
  • @NotAVeryGoodDeveloper no worries ;) – Nick Parsons Dec 15 '19 at 03:06
  • Be aware that `flat` and `flatMap` are fairly recent additions to the language. If you are unfortunate enough to be working with IE11, they won't work. A lot of business-to-business stuff still uses IE. – Jeremy J Starcher Dec 15 '19 at 07:02
  • @JeremyJStarcher yeah, unfortunately it does have poor browser comparability. I would recommend using a polyfill or a transpiler such as Babel if comparability is an issue for OP – Nick Parsons Dec 15 '19 at 07:22
0

Use the map() function twice, once to grab the arrays, and again to grab the words in them:

let arr1 = ["one", "two", "three"];
let arr2 = ["four", "five", "six"];

function calc_arr(...args) {
    return args.map((arr) => {
       return arr.map((word) => {
           return word.length;
       })
    })
}

const res = calc_arr(arr1,arr2);
console.log(res);
symlink
  • 11,984
  • 7
  • 29
  • 50