'Looping data from json using Array

I'm trying to write a function but I doesn't make it. This function works like that

Input: changeSetting("a>b>c","hello")

After that "setting" named value change from {} to {"a":{"b":{"c":"hello"}}}

If input is changeSetting("a","hello") json become {} to {"a":"hello"}

My last code attempt:

function changeSetting(name,val)  {
  if (name.includes(">")) {
    name = name.split('>')
    let json = {}
    name.map((el,i)=>{
    let last = "" 
    name.filter(el=>!name.slice(i+1).includes(el)).map(el=> {
    if(last!="") {
      json[el] = {}
    }})
    }) 
  }
 }

How can we make this ? (Optimization not important but if is it good for me)



Solution 1:[1]

const changeSetting = (setting, target) => {
  if (setting.length < 2) {
    return {
      [setting]: target
    }
  } else {

    const keys = setting.split('>');

    return keys.reduceRight((acc, curr, i) => {

      console.log(acc);

      if(i === keys.length - 1) {
        return acc = {[curr] : target}    
      }
      
        return acc = { [curr]: acc };
    }, {})

    
  }
}


console.log(changeSetting('a', 'hello'));
console.log(changeSetting('a>b>c', 'hello'));

Solution 2:[2]

function changeSetting(inputProperties, value) {
  let result;
  const properties = inputProperties.split(">");
  result = `{${properties
    .map((property) => `"${property}":`)
    .join("{")}"${value}"${"}".repeat(properties.length)}`;
  return result;
}
changeSetting("a>b>c", "hello");
changeSetting("a", "hello");

Solution 3:[3]

As you work with strings - you may try to use JSON like this:

function changeSetting(name, val) {
  const keys = name.split(">");
  return JSON.parse(
    [
      "{",
      keys.map((key) => `"${key}"`).join(":{"),
      ":",
      `"${val}"`,
      "}".repeat(keys.length),
    ].join("")
  );
}

Solution 4:[4]

There's multiple ways to do this, I've commented the snippet

const changeSetting = (name, val) => {
    
    // Split and reverse the name letters
    const nameSplit = name.split('>').reverse();

    // Set up the inner most object
    let newObj = {[nameSplit[0]]:val}

    // Now remove the first letter and recurse through the rest
    nameSplit.slice(1).forEach((el, idx) => newObj = {[el]: newObj});

    console.log(newObj);
}

changeSetting("a>b>c", "hello")
changeSetting("a", "hello")
changeSetting("a>b>c>d>e>f>g", "hello")

Solution 5:[5]

You can create an array by splitting name on all > with String.prototype.split(), and then Array.prototype.reduceRight() the created array of elements with an object initial value {} and adding key value pairs but on the last element the value should be variable val.

Code:

const changeSetting = (name, val) => name
  .split('>')
  .reduceRight((a, c, i, arr) => ({ 
    [c]: i === arr.length - 1 ? val : a 
  }), {})

console.log(changeSetting('a>b>c', 'hello'))
console.log(changeSetting('a', 'hello'))
console.log(changeSetting('a>b>c>d>e>f>g', 'hello'))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3 Yuri
Solution 4
Solution 5