Сделайте короткую версию JSON, объединив пары ключ-значение

#javascript #json

Вопрос:

У меня есть json

 input_lookup = [{"keyprefixname": "fruit","resultkey":"sweet" }, 
{"keyprefixname": "rate","resultkey":"ratex" }]

input = {
'fruit_a': "red apple"
'fruit_b': "green apple"
'rate_a': "10$"
'rate_b': "20$"
'vegetable_a': "spinach"
'vegetable_b': "carrot"
}
 

Входной json содержит некоторые префиксы, перечисленные в поиске, и нам нужно объединить перечисленные, образуя новые пары ключей json с комбинированным значением

ожидаемый результат составляет

 result_output = {
'sweet': "red apple,green apple"
'ratex': "10$,20$"
'vegetable_a': "spinach" // not to combine this since it wont exist in lookup
'vegetable_b': "carrot"
}
 

Я пробовал с

 result_output = {}
for(key in input_lookup){
if(key.indexOf(input_lookup) > -1)
key = key  input_lookup[key]
}
 

Ответ №1:

Есть несколько способов сделать это. Вот редуктор, используемый Array.find для сравнения значений поиска со значением из входных данных:

 const lookup = [
  {prefix: "fruit", key: "sweet" }, 
  {prefix: "rate", key: "ratex" },
];

const input = {
  fruit_a: "red apple",
  fruit_b: "green apple",
  rate_a: "10$",
  rate_b: "20$",
  vegetable_a: "spinach",
  vegetable_b: "carrot",
};

const reducedWithArrayOfValues = Object.entries(input)
  .reduce( (acc, [key, value]) => {
    const nwKey = lookup.find(v => key.startsWith(v.prefix));
    return nwKey 
      ? { ...acc, [nwKey.key]: (acc[nwKey.key] ||[]).concat(value) }
      : { ...acc, [key]: value };
  }, {}
);

const reducedWithStringValues = Object.entries(input)
  .reduce( (acc, [key, value]) => {
    const nwKey = lookup.find(v => key.startsWith(v.prefix));
    return nwKey 
      ? { ...acc, [nwKey.key]: `${acc[nwKey.key] ? `${
          acc[nwKey.key]}#` : ""}${value}` }
      : { ...acc, [key]: value };
  }, {}
);

document.querySelector(`pre`).textContent = 
  JSON.stringify(reducedWithStringValues, null, 2);
document.querySelector(`pre`).textContent  = `n---n${ 
  JSON.stringify(reducedWithArrayOfValues, null, 2)}`; 
 <pre></pre> 

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

1. Это самый многообещающий ответ. Могу ли я узнать, к какой строке я могу присоединиться с помощью разделителя? вместо красного яблока-зеленое яблоко. Я хотел бы иметь красное яблоко#зеленое яблоко

2. Привет @user16731842, добавлен второй редуктор reducedWithStringValues , доставляющий нужные строки

Ответ №2:

вот, пожалуйста

 function getAggregateKey(key, value) {
    const result = input_lookup.find((item) => key.includes(item.keyprefixname));
    if (result) {
        return result["resultkey"];
    }
    return key;
}

const arrayObject = Object.entries(input).reduce((acc, cur) => {
    const aggKey = getAggregateKey(cur[0]);
    if (!(aggKey in acc)) {
        acc[aggKey] = [];
    } 
    acc[aggKey].push(cur[1])
    return acc;
}, {});

const result = Object.entries(arrayObject).reduce((acc, cur) => {
    acc[cur[0]] = cur[1].join(',');
    return acc;
}, {});

console.log(result);
 

Ответ №3:

 let input_lookup  = [{
  "keyprefixname": "fruit",
  "resultkey": "sweet"
}, {
  "keyprefixname": "rate",
  "resultkey": "ratex"
}];

let input  = {
  'fruit_a': "red apple",
  'fruit_b': "green apple",
  'rate_a': "10$",
  'rate_b': "20$",
  'vegetable_a': "spinach",
  'vegetable_b': "carrot"
};


// first we need a good lookup object the default is an array 
// we made fruit > sweet and rate > ratex 
// this is help later in the code
var good_lookup = {};
for(let i = 0; i < input_lookup.length ; i  ){
    let good_key = input_lookup[i]['keyprefixname'];
  let good_val = input_lookup[i]['resultkey'];
    good_lookup[good_key] = good_val;
}

let result_output = {};

for(let key in input ){
  let to_lookup = key.split('_');
  let to_lookup_key = to_lookup[0];//fruit, rate
  var to_aggregate = good_lookup[to_lookup_key];
  if(to_aggregate){
        if(result_output[to_aggregate]){
        result_output[to_aggregate] = result_output[to_aggregate]   ", "   input[key];
      } else {
            result_output[to_aggregate] = input[key];
      }
  } else {
      result_output[key] = input[key]; 
  }
}

console.log(result_output);
 

вот скрипка для кода https://jsfiddle.net/z8usmgja/1/