Как мне преобразовать вложенный массив в массив с ключом в JavaScript?

#javascript #arrays

#javascript #массивы

Вопрос:

У меня есть вложенный массив, который выглядит следующим образом:

[["Organisation","ID","Name"],["ACME","123456","Bart Simpson"],["ACME","654321","Ned Flanders"],["ACME","1234","Edna Kabappel"],["Yahoogle","666666","Bon Scott"],["Yahoogle","99999","Neil Young"],["Yahoogle","111111","Shania Twain"]]

Первое значение в каждом массиве — это название организации, которой могут принадлежать идентификатор и имя.

Я пытаюсь найти самый простой способ сгруппировать все экземпляры, в которых идентификатор и имя принадлежат одной и той же компании, под одним «ключом».

Итак, вышесказанное приведет к чему-то вроде этого:

 {
   "ACME": [
      {
         "ID": 123456,
         "Name": "Bart Simpson"
      },
      {
         "ID": 654321,
         "Name": "Ned Flanders"
      },
      {
         "ID": 1234,
         "Name": "Edna Kabappel"
      }
   ],
   "Yahoogle": [
      {
         "ID": 666666,
         "Name": "Bon Scott"
      },
      {
         "ID": 99999,
         "Name": "Neil Young"
      },
      {
         "ID": 111111,
         "Name": "Shania Twain"
      }
   ]
}
 

Я поиграл с циклами for, но в итоге получаю много-много строк кода, пытаясь определить, когда название компании отличается от предыдущего, и попадаю в настоящую неразбериху с вещами.

Я много искал здесь, пытаясь найти что-то подобное, но безуспешно.

Я только что снова начал кодировать для личного интереса примерно через 18 лет, и я снова очень новичок.

Заранее благодарю вас за любую помощь.

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

1. Ваш вопрос несколько расплывчатый. Вы, должно быть, что-то пробовали, и в идеале мы хотели бы увидеть, к чему вы пришли — покажите нам вашу попытку решения, ошибки или нет. Потому что есть несколько способов сделать то, что вы хотите, и «простой» может означать разные вещи для разных людей и в разных контекстах. Самый короткий код? Код, адаптированный для новичков? Хорошая производительность?

2. Спасибо @amn, комментаторы дали отличные ответы, и это очень помогло. Я осознавал длину своего вопроса и пытался сделать его как можно более понятным. В следующий раз я предоставлю свои попытки и буду более ясен, к какому результату я стремлюсь.

Ответ №1:

множество решений для получения одного и того же результата, одно с использованием lambda и reduce: это общее решение, просто адаптируйте вывод push для создания вашего окончательного json.

 const datas = [
  ["Organisation", "ID", "Name"],
  ["ACME", "123456", "Bart Simpson"],
  ["ACME", "654321", "Ned Flanders"],
  ["ACME", "1234", "Edna Kabappel"],
  ["Yahoogle", "666666", "Bon Scott"],
  ["Yahoogle", "99999", "Neil Young"],
  ["Yahoogle", "111111", "Shania Twain"]
];

const titles = datas.shift()
const groupBy = (x,f)=>x.reduce((a,b)=>((a[f(b)]||=[])
                        .push({[titles[1]]:b[1], [titles[2]]:b[2]}),a),{});

const result = groupBy(datas, v => v[0])

console.log(result) 

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

1. Спасибо @Frenchy!

Ответ №2:

Использование Array.reduce. Пожалуйста, проверьте, работает ли это для вас. В приведенном ниже подходе ID и Name жестко запрограммирован. Вы можете попробовать написать общий динамический подход, который обрабатывает любое количество параметров, таких как ID, Name, Age и т.д.

 const myArray = [
  ["Organisation", "ID", "Name"],
  ["ACME", "123456", "Bart Simpson"],
  ["ACME", "654321", "Ned Flanders"],
  ["ACME", "1234", "Edna Kabappel"],
  ["Yahoogle", "666666", "Bon Scott"],
  ["Yahoogle", "99999", "Neil Young"],
  ["Yahoogle", "111111", "Shania Twain"]
];

const obj = myArray.reduce((acc, value, index) => {
  if (index === 0) return acc;
  const key = value[0];

  if (!acc[key]) {
    acc[key] = [];
  }

  acc[key].push({
    ID: value[1],
    Name: value[2]
  });

  return acc;
}, {});

console.log(obj); 

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

1. Спасибо @kiranvj в этом случае входящие данные предсказуемы по своей структуре, поэтому жесткое кодирование в порядке.

Ответ №3:

Чтобы достичь желаемого, вы можете выполнить следующие действия:

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

Ниже приведен пример реализации, предполагающий, что ваши данные хранятся в data :

 var result = {};
for(var i=1; i < data.length; i  ){
    if(!result.hasOwnProperty(data[i][0])){        
        result[data[i][0]] = [];
    }
    result[data[i][0]].push({ "ID": data[i][1], "Name": data[i][2]});
}
 

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

1. Это работает очень хорошо большое вам спасибо @Nishesh Pratap Singh