как преобразовать объект в сложный массив объекта

#javascript

#javascript

Вопрос:

У меня есть такой объект

 const data = {offer_4: "5", note_4: "note", offer_6: "5", note_6: "note"}
 

если мне нужно преобразовать в массив объектов следующим образом, как это можно сделать?

 const body = [
              {
                id: 4,// after underline is id
                is_disable: //value of offer_4 === undefined ? false : true,
                price: //value of offer_4,
                note: //value of note_4,
              },
              {
                id: 6,// after underline is id
                is_disable: //value of offer_6 === undefined ? false : true,
                price: //value of offer_6,
                note: //value of note_6,
              },
            ];
 

у нас есть ключ типа offer_4, номер предложения «_» — это идентификатор, поэтому, когда у меня есть ключ note_4 и offer_4, эти значения должны быть в одном объекте
, если предложение имеет значение, тогда is_disabled должно быть истинным значением, в противном случае должно быть ложным предложение и примечание всегда вместе
Надеюсь, мое объяснение понятно,

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

1. где корреляция между ними?

2. Это не сервис для написания кода. Покажите, что вы пробовали.

3. @Alex у нас есть ключ типа offer_4, номер предложения «_» — это идентификатор, поэтому, когда у меня есть ключ note_4 и offer_4, эти их значения должны быть в одном объекте

4. @mplungjan Я тестирую все ответы, и это лучше, чем другое, поэтому я снова тестирую все ответы на ваши вопросы

5. Пожалуйста, добавьте полный пример с предложениями и без них

Ответ №1:

 const data = {offer_4: "5", note_4: "note", offer_6: "5", note_6: "note", note_7: "note"}
   

const reduced = Object.keys(data).reduce((acc,val) =>{
 const id = val.split('_')[1];
 if (acc[id]) return acc;
 acc[id] = {
    id, is_disabled: data[`offer_${id}`] === undefined, price: data[`offer_${id}`] || 0, note: data[`note_${id}`]
 }
 return acc;
}, {});

console.log(Object.values(reduced)) 

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

1. Это из-за неопределенного значения??

2. Оператор if предотвращает его обновление

3. Я имею в виду, что если бы у входного объекта однажды был description_4 тогда, вам пришлось бы обновить свой код. В любом случае это хороший ответ на конкретный вопрос

Ответ №2:

вот что вам нужно сделать :

 const data = { offer_4: "5", note_4: "note", offer_6: "5", note_6: "note", note_7: "note"}
   

const resultArray = [];
for (const key of Object.keys(data)) {
  if (key.includes("offer")) {
    const _id = key.split("_")[1];
    const newItem = {
      id: _id, 
      is_disable: data[key] === undefined,
      price: data[key],
      note: data[`note_${_id}`], 
    };
    resultArray.push(newItem);
  }
}

console.log(resultArray); 

Ответ №3:

Пожалуйста, обратите внимание, что каждое note объединение с offer станет объектом. В противном случае это не так.

 if (acc[id]  
        || (splitValues[0] === "offer" amp;amp; data[`note_${id}`] === undefined)
        || (splitValues[0] === "note" amp;amp; data[`offer_${id}`] === undefined)) return acc;
 
 const data = {offer_4: "5", note_4: "note", offer_6: "5", note_6: "note", note_7: "note"}
   
const result = Object.entries(data).reduce((acc, [key, value]) =>{
 const splitValues = key.split('_');
 const id = splitValues[1];
 if (acc[id]  
    || (splitValues[0] === "offer" amp;amp; data[`note_${id}`] === undefined)
    || (splitValues[0] === "note" amp;amp; data[`offer_${id}`] === undefined)) return acc;
    
 acc[id] = {
      id, 
      is_disabled: data[`offer_${id}`] !== undefined, 
      price: data[`offer_${id}`], 
      note: data[`note_${id}`]
   }
 return acc;
}, {});

console.log(Object.values(result)); 

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

1. tnx для ответа на эту часть is_disabled: data[ offer_${id} ] !== undefined должно быть is_disabled: data[ offer_${id} ] === undefined, и для моей ситуации предложение и примечание всегда вместе, поэтому не нужно проверять его

Ответ №4:

Я бы попробовал уменьшить — обратите внимание, что я обрабатываю неопределенное предложение в id 7

 const data = {
offer_4: "5", note_4: "note", 
offer_6: "5", note_6: "note" , 
note_7: "note"};
       
const body = Object.keys(data).reduce((acc,key) => {
  const [dataKey, dataId] = key.split("_");
  let obj = acc.find(({id}) => id===dataId)
  if (!obj) acc.push({id:dataId})
  obj = acc[acc.length-1];
  if (dataKey === "offer") {
    obj["price"] = data[key]
  }
  else obj[dataKey] = data[key]; // will add any new key too

  return acc
},[])
body.forEach(item => item["is_disable"]=!item["price"]);
console.log(body) 

Ответ №5:

Довольно обширный подход, а не такой чистый и короткий. Но вот мы идем:

 const data = {
  offer_4: "5",
  note_4: "note",
  offer_6: "5",
  note_6: "note"
};

let body = [];

function getByColumn(arr, col, val) {
  for (var elem of arr) {
    if (elem[col] === val) {
      return elem;
    }
  }
  return false;
}

function removeElemByColumn(arr, col, val) {
  body = [];
  for (var elem of arr) {
    if (elem[col] !== val) {
      body.push(elem);
    }
  }
  return body;
}

for (var key in data) {
  let field = key.split('_')[0];
  let id = key.split('_')[1];
  let value = data[key];
  let is_disable = field === 'offer' amp;amp; value > 0;
  let elem = getByColumn(body, 'id', id);

  if (elem) {
    elem[field] = value;
    elem.is_disable = elem.is_disable || is_disable;
    body = removeElemByColumn(body, 'id', id);
    body.push(elem);
  } else {
    elem = {};
    elem.id = id;
    elem[field] = value;
    elem.is_disable = is_disable;
    body.push(elem);
  }
}

console.log(body); 

Ответ №6:

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

 const
    data = { offer_4: "5", note_4: "note", offer_6: "5", note_6: "note" },
    result = Object.values(Object.entries(data).reduce((r, [k, v]) => {
        let [type, id] = k.split('_');
        id *= 1;
        type
        if (!r[id]) r[id] = { id, is_disable: false, price: undefined, note: undefined };
        if (type === 'offer' amp;amp; v !== undefined) r[id].is_disable = true;
        if (type === 'offer') type = 'price';
        r[id][type] = v;
        return r;
    }, {}));

console.log(result);