Есть ли какой-либо способ преобразовать строку с помощью объектно-объектного синтаксиса?

#javascript #arrays #typescript #object #parsing

#javascript #массивы #машинописный текст #объект #синтаксический анализ

Вопрос:

Данная функция дает мне следующую обратную связь:

 [
    "users[0].name is invalid",
    "date is invalid",
    "address.ZIP is invalid"
]
 

Как я могу взять этот вывод с помощью синтаксиса объекта и преобразовать его во что-то вроде:

 {
     users: [{name: 'is invalid'}],
     date: 'is invalid',
     address: {
        ZIP: 'is invalid'
    }
}
 

Комментарии:

1. Похоже, он был создан наоборот. Регулярное выражение — это палка о двух концах, но, вероятно, вам это понадобится.

2. «вывод с объектным синтаксисом» ? Это массив с двумя сообщениями об ошибках, причем одно из них имеет странный формат o.O

Ответ №1:

Вы могли бы разделить строку на адресную часть и значение, получить правильную структуру и присвоить значение.

 const
    setValue = (object, address, value) => {
        const
            hasBrackets = s => /^[. ]$/.test(s),
            path = address.split(/.|(?=[)/),
            types = path.map((_, i, a) => hasBrackets(a[i   1]) ? [] : {}),
            keys = path.map(s => hasBrackets(s) ? s.slice(1, -1) : s),
            last = keys.pop();

        keys.reduce((r, k, i) => r[k] ??= types[i], object)[last] = value;
    },
    data = ["users[0].name is invalid", "date is invalid", "address.ZIP is invalid"],
    result = data.reduce((r, s) => {
        const [k, v] = s.match(/[^s] |. $/g);
        setValue(r, k, v.slice(1)) ;
        return r;
    }, {});

console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

Ответ №2:

Вы можете рекурсивно уменьшить ключи, сначала определив ключи, а затем выполнив итерацию по парам ключ / значения и уменьшив их до результирующего объекта.

 const main = () => {
  const data = [
    "users[0].name is invalid",
    "users[0].address is invalid",
    "users[1].title is invalid",
    "date is invalid",
    "address.ZIP is invalid"
  ];

  console.log(apply(data));
};

const apply = (data) =>
  data.reduce((result, val, index) => {
    const
      pos = val.indexOf(' '),
      key = val.substring(0, pos),
      value = val.substring(pos   1);
    applyPair(result, key, value);
    return resu<
  }, {});

const applyPair = (ref, key, value) => {
  const [headKey, ...tailKeys] = key.split(/./);
  if (headKey.endsWith(']')) {
    const [ arrKey, arrIndex ] = parseArrayKey(headKey);
    ref[arrKey] = ref[arrKey] || [];
    const obj = ref[arrKey][arrIndex] || {};
    applyPair(obj, tailKeys.join('.'), value);
    ref[arrKey][arrIndex] = obj;
  } else {
    if (tailKeys.length > 0) {
      const objKey = headKey;
      ref[objKey] = {};
      applyPair(ref[objKey], tailKeys.join('.'), value);
    } else {
      ref[key] = value;
    }
  }
};

const parseArrayKey = (key) =>
  (([m, k, i]) => [k, parseInt(i, 10)])(key.match(/^(w )[(d )]$/));

main(); 
 .as-console-wrapper { top: 0; max-height: 100% !important; } 

Результат

 {
  "users": [
    {
      "name": "is invalid",
      "address": "is invalid"
    },
    {
      "title": "is invalid"
    }
  ],
  "date": "is invalid",
  "address": {
    "ZIP": "is invalid"
  }
}