Получить все ключи в массиве объектов, значения которых являются массивами - PullRequest
3 голосов
/ 30 марта 2020

Я пытаюсь записать все ключи в массив объекта, значения которого являются массивами, в новый массив. Без дубликатов. Что является лучшим способом в javascript, без библиотек, таких как loda sh или подчеркивание. Я думаю, что мое решение определенно улучшено. Отдельные объекты и их ключи являются переменными и не всегда идентичны. Предложения приветствуются.

Предполагаемый вывод для моего примера должен быть следующим: ["stuff", "type", "mis c", "нечто"]

const items = [{
    name: "Joe",
    occupied: "no",
    mobile: "yes",
    treatment: "no",
    date: "29-03-2020",
    age: "15",
    stuff: ["A", "B", "C"],
    type: ["1", "2"]
  },
  {
    name: "Jack",
    occupied: "yes",
    mobile: "no",
    treatment: "no",
    date: "02-03-2020",
    age: "20",
    stuff: ["A", "B", "C", "D", "E"],
    type: ["8", "6"],
    misc: ["otherStuff", "someStuff"]
  },
  {
    name: "Jane",
    occupied: "no",
    mobile: "yes",
    treatment: "yes",
    date: "15-02-2020",
    age: "28",
    stuff: ["C", "D", "E"],
    type: ["4", "7"],
    something: ["xxx", "ccc"]
  }
];


function getKeysWithArrayValues(myArray) {
  const result = [];
  myArray.forEach(item => Object.entries(item).forEach(itm => itm.filter(Array.isArray).forEach(x => result.push(itm.slice(0, 1)))));
  return flatArray(result)
};

function flatArray(array) {
  return array.reduce((acc, val) => Array.isArray(val) ? acc.concat(flatArray(val)) : acc.concat(val), []);
};
const ttt = getKeysWithArrayValues(items);
const flat = Array.from(new Set(ttt))
console.log(flat);

Ответы [ 5 ]

2 голосов
/ 30 марта 2020

вот мое решение, надеюсь, оно поможет. Алгоритм вполне понятен, и я полагаю, что не нужно много объяснять. Мы просто go через массив используем метод Reduce и, наконец, создаем новый массив, содержащий только ключи, которые соответствуют нашим требованиям.

Array.isArray (rec [key]) проверяет, является ли значение массивом.

a cc .indexOf (ключ) <0 проверяет, был ли ключ уже включен в результирующий массив на одном из предыдущих шагов ios. </p>

const arr_ = items
  .reduce((acc, rec) => {
    return [...acc, ...Object.keys(rec).filter(key => Array.isArray(rec[key]) && acc.indexOf(key) < 0)]
  }, [])
1 голос
/ 30 марта 2020

Еще один способ с Object.fromEntries, flatMap и filter.

const items = [
  {
    name: "Joe",
    occupied: "no",
    mobile: "yes",
    treatment: "no",
    date: "29-03-2020",
    age: "15",
    stuff: ["A", "B", "C"],
    type: ["1", "2"]
  },
  {
    name: "Jack",
    occupied: "yes",
    mobile: "no",
    treatment: "no",
    date: "02-03-2020",
    age: "20",
    stuff: ["A", "B", "C", "D", "E"],
    type: ["8", "6"],
    misc: ["otherStuff", "someStuff"]
  },
  {
    name: "Jane",
    occupied: "no",
    mobile: "yes",
    treatment: "yes",
    date: "15-02-2020",
    age: "28",
    stuff: ["C", "D", "E"],
    type: ["4", "7"],
    something: ["xxx", "ccc"]
  }
];

const keys = Object.keys(
  Object.fromEntries(
    items.flatMap(item =>
      Object.entries(item).filter(([, value]) => Array.isArray(value))
    )
  )
);

console.log(keys);
1 голос
/ 30 марта 2020

Вы можете взять Set и получить уникальные ключи объектов.

const
    items = [{ name: "Joe", occupied: "no", mobile: "yes", treatment: "no", date: "29-03-2020", age: "15", stuff: ["A", "B", "C"], type: ["1", "2"] }, { name: "Jack", occupied: "yes", mobile: "no", treatment: "no", date: "02-03-2020", age: "20", stuff: ["A", "B", "C", "D", "E"], type: ["8", "6"], misc: ["otherStuff", "someStuff"] }, { name: "Jane", occupied: "no", mobile: "yes", treatment: "yes", date: "15-02-2020", age: "28", stuff: ["C", "D", "E"], type: ["4", "7"], something: ["xxx", "ccc"] }],
    keys = Array.from(
         items.reduce(
             (s, o) => Object
                  .keys(o)
                  .reduce((t, k) => Array.isArray(o[k]) ? t.add(k) : t, s),
             new Set
        )
    );

console.log(keys);
1 голос
/ 30 марта 2020

Вы можете использовать set и Array.isArray (), чтобы проверить, является ли значение массивом.

let mySet = new Set();    const items = [{name: "Joe",occupied: "no",mobile: "yes",treatment: "no",date: "29-03-2020",age: "15",stuff: ["A", "B", "C"],type: ["1", "2"]},{name: "Jack",occupied: "yes",mobile: "no",treatment: "no",date: "02-03-2020",age: "20",stuff: ["A", "B", "C", "D", "E"],type: ["8", "6"],misc: ["otherStuff", "someStuff"]
}, {name: "Jane",occupied: "no",mobile: "yes",treatment: "yes",date: "15-02-2020",age: "28",stuff: ["C", "D", "E"],type: ["4", "7"],something: ["xxx", "ccc"]}];

items.forEach((obj)=> Object.keys(obj).forEach( prop=>{if(Array.isArray(obj[prop])) 
mySet.add(prop)})); console.log(Array.from(mySet));
.as-console-wrapper { max-height: 100% !important; top: 0; }
1 голос
/ 30 марта 2020

Используйте flatMap для перебора ключей каждого объекта и возврата отфильтрованного массива ключей при условии, является ли значение в этом ключе массивом:

const items=[{name:"Joe",occupied:"no",mobile:"yes",treatment:"no",date:"29-03-2020",age:"15",stuff:["A","B","C"],type:["1","2"]},{name:"Jack",occupied:"yes",mobile:"no",treatment:"no",date:"02-03-2020",age:"20",stuff:["A","B","C","D","E"],type:["8","6"],misc:["otherStuff","someStuff"]},{name:"Jane",occupied:"no",mobile:"yes",treatment:"yes",date:"15-02-2020",age:"28",stuff:["C","D","E"],type:["4","7"],something:["xxx","ccc"]}];

const keysWithArrays = new Set(
  items.flatMap(
    item => Object.keys(item).filter(key => Array.isArray(item[key]))
  )
);
console.log([...keysWithArrays]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...