0

I have seen the questions but none of them helped me. I have a string like this:

var Lang_Array1 = "HU,blah,blah,blah,EN,blah,blah,blah,blah,DE,blah,blah,blah,RO,blah,blah,blah";

I want that string to be in different arrays based on the separators "HU", "EN", "DE", "RO".

My approach currently is this(Working but not too elegant):

var Lang_Array1 = Lang_Array.split(",");
    console.log(typeof(Lang_Array));
    console.log(Lang_Array);

    var HU_Langs = [];
    var EN_Langs = [];
    var DE_Langs = [];
    var RO_Langs = [];

    for(var i = 0; i < Lang_Array1.length;i++){
        if(Lang_Array1[i] != "EN"){
            if(Lang_Array1[i] != ""){
                HU_Langs[i] = Lang_Array1[i];
            }
        }else{
            for(i;i < Lang_Array1.length;i++){
                if(Lang_Array1[i] != "DE"){
                    if(Lang_Array1[i] != ""){
                        EN_Langs[i] = Lang_Array1[i];
                    }
                }else{
                    for(i;i < Lang_Array1.length;i++){
                        if(Lang_Array1[i] != "RO"){
                            if(Lang_Array1[i] != ""){
                                DE_Langs[i] = Lang_Array1[i];
                            }
                        }else{
                            for(i;i < Lang_Array1.length;i++){
                                    if(Lang_Array1[i] != ""){
                                        RO_Langs[i] = Lang_Array1[i];
                                    }       
                                }
                            break;
                        }
                    }
                    break;
                }
            }
            break;
        }
    }

That way i get what i want but i want to improve it somehow. The arrays:

HU_Langs =["HU","blah","blah","blah"];
EN_Langs =["EN","blah","blah","blah"];
DE_Langs =["DE","blah","blah","blah"];

etc...

So how can i improve this code without nested for loops?

EDIT: Thank you for all! All the answers are very very good. My question wasnt clear and detailed enough but i solved it like this with the help of the correct answer.

Here is the function now:

function Get_Language_Object(Lang_Array){
    Lang_Array = Lang_Array.replace(/(\r\n|\n|\r)/gm, "");
    var langs = ['HU', 'EN', 'DE', 'RO'];
    var isLang = str => langs.includes(str);
    var { HU: New_HU_Langs, EN: New_EN_Langs, DE: New_DE_Langs, RO: New_RO_Langs } = Lang_Array.split(',')
        .reduce((r, str) => {
    if(isLang(str)) r.push([]);
        r[r.length - 1].push(str);
        return r;
    }, [])
        .reduce((r, [code, ...arr]) => ({ ...r, [code]: arr }), {});
    for(var i = 0; i < TAGS.length;i++){
        arrLang.HU[TAGS[i]] = New_HU_Langs[i];
        arrLang.EN[TAGS[i]] = New_EN_Langs[i];
        arrLang.DE[TAGS[i]] = New_DE_Langs[i];
        arrLang.RO[TAGS[i]] = New_RO_Langs[i];
    }
    Set_Actual_Language();
    VNotify("Settings Notfy","Lang Set!","success",1500,"success32.png");
}
2
  • If your code is working but you want to improve it, then this question is for codereview, not for StackOverflow Commented Jan 6, 2020 at 12:41
  • Wouldn't you just split on comma and read each token until you hit a new LANG type? Commented Jan 6, 2020 at 12:42

5 Answers 5

3

Split the string by the delimiter (,), reduce the array, and for every language code, add a new sub-array. Push all items to the last sub-array:

var Lang_Array1 = "HU,blah,blah,blah,EN,blah,blah,blah,blah,DE,blah,blah,blah,RO,blah,blah,blah";

var langs = ['HU', 'EN', 'DE', 'RO'];

var isLang = str => langs.includes(str);

var result = Lang_Array1.split(',')
  .reduce((r, str) => {
    if(isLang(str)) r.push([]);
    
    r[r.length - 1].push(str);
  
    return r;
  }, []);
  
console.log(result);

If you want to split to multiple arrays, reduce the sub-arrays to an object, and use desturcturing to assign them to variables:

var Lang_Array1 = "HU,blah,blah,blah,EN,blah,blah,blah,blah,DE,blah,blah,blah,RO,blah,blah,blah";

var langs = ['HU', 'EN', 'DE', 'RO'];

var isLang = str => langs.includes(str);

var { HU: HU_Langs, EN: EN_Langs, DE: DE_langs, RO: RO_langs } = Lang_Array1.split(',')
  .reduce((r, str) => {
    if(isLang(str)) r.push([]);
    
    r[r.length - 1].push(str);
  
    return r;
  }, [])
  .reduce((r, [code, ...arr]) => ({ ...r, [code]: arr }), {});
  
console.log(HU_Langs, EN_Langs, DE_langs, RO_langs);

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

5 Comments

Sorry, i wasn't clear. I want to split it to multiple arrays, i edited my post. like this: HU_Langs =["HU","blah","blah","blah"]; EN_Langs =["EN","blah","blah","blah"]; DE_Langs =["DE","blah","blah","blah"];
Thank you very much! You second comment is working perfectly.Hovewer the first is the best because i would improve my implementation further withyour help. The thing is that your first answer is better for me just not in that way. I have all the languages inside an object and i would be able to skip 1-2 steps from this code:
Oh can't insert the code in here because its too long. :(
Create a jsfiddle/codepen/etc... and post the link in the comments.
I updated my post but i uploaded it to pastebin: pastebin.com/iFBjPa9w
0

You should reduce the list of words after splitting on your delimiter (,). Each time you run into a known key, you alter the key that refers to the current language.

This is the most succinct example:

let arr = "HU,blaf,blaf,blaf,EN,blah,blah,blah,blah,DE,bla,bla,bla,RO,bah,bah,bah"
let keys = [ "DE", "EN", "HU", "RO" ]
let dict = langDict(arr, keys)

console.log(dict)

function langDict(arr, keys) {
  let key = null
  return arr.split(/,/g).reduce((dict, token) => {
    if (Object.keys(dict).length && key == null) {
      throw new Error('No language defined yet!')
    } else if (keys.includes(token)) {
      key = token
    } else {
      if (dict[key] == null) dict[key] = []
      dict[key].push(token)
    }
    return dict
  }, {})
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

Comments

0

As I believe the upper case ISO2 code is the language hint, you could group all results together in a more scalable way.

var Lang_Array1 = "HU,blah,blah,blah,EN,blah,blah,blah,blah,DE,blah,blah,blah,RO,blah,blah,blah";
var Languages = {};
var current = '';

Lang_Array1.split(',').forEach(function (value) {
  if (/^[A-Z]{2}$/.test(value))
    current = value;
  else
    Languages[current] = (Languages[current] || []).concat(value);
});

console.log(Languages);

Above snippet would populate the Languages object like this:

{
  "HU": [
    "blah",
    "blah",
    "blah"
  ],
  "EN": [
    "blah",
    "blah",
    "blah",
    "blah"
  ],
  "DE": [
    "blah",
    "blah",
    "blah"
  ],
  "RO": [
    "blah",
    "blah",
    "blah"
  ]
}

At this point, all you have to do is to address directly Languages.EN or others, or recreate the original structure via:

var Lang_Array = Object.keys(Languages).reduce(
  function (arr, key) {
    return arr.concat(key, Languages[key]);
  },
  []
);

You could also create arrays with the language starting at index 0, and values following:

var Lang_EN = ['EN'].concat(Languages.EN);

As summary, grouping by keys seem the best way to represent, and manipulate, such flattened structure.

I hope this helped 👋

Comments

0

If the order is constant:

var Lang_Array1 = "HU,blah1,blah2,blah3,EN,blah4,blah5,blah6,blah7,DE,blah8,blah9,blah10,RO,blah11,blah12,blah13";
const arr1 = Lang_Array1.split(/[HU,EN,DE,RO]/g);
let obj = {hu:[],en:[],de:[],ro:[]};
const keys = Object.keys(obj);
let i = 0;
arr1.forEach(el=>{
    if(el !== '')
      obj[ keys[i] ].push(el);
  else
    if(obj[ keys[i] ].length > 0)
      i++;
 });

console.log(obj);

Response:

{hu: Array(3), en: Array(4), de: Array(3), ro: Array(3)}
hu: (3) ["blah1", "blah2", "blah3"]
en: (4) ["blah4", "blah5", "blah6", "blah7"]
de: (3) ["blah8", "blah9", "blah10"]
ro: (3) ["blah11", "blah12", "blah13"]

Comments

0

Temporary array can be used to reference the array to push to :

var Lang_Array = "HU,blah,blah,blah,EN,blah,blah,blah,blah,DE,blah,blah,blah,RO,blah,blah,blah";
var Lang_Array1 = Lang_Array.split(","), HU_Langs = [], EN_Langs = [], DE_Langs = [], RO_Langs = [];

for (var Langs = [], i = 0; i < Lang_Array1.length; i++)
{
  var str = Lang_Array1[i];

  Langs = { HU: HU_Langs, EN: EN_Langs, DE: DE_Langs, RO: RO_Langs }[str] || Langs;

  Langs.push(str);
}

console.log( HU_Langs, EN_Langs, DE_Langs, RO_Langs );

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.