【问题标题】:Add consecutive alphabet letters as object keys添加连续的字母作为对象键
【发布时间】:2018-09-13 15:44:05
【问题描述】:

我想创建一个具有给定结构的对象:

const questions = [
  {
    id: '1',
    instruction: 'Question1',
    options: {
      'a': 'SomeText1',
      'b': 'SomeText2',
      'c': 'SomeText3'
    },
    correct: ['c']
  },
  {
    id: '2',
    instruction: 'Question2',
    options: {
      'a': 'SomeText1',
      'b': 'SomeText2',
      'c': 'SomeText3',
      'd': 'SomeText4'
    },
    correct: ['a']
  },
  {
    id: '3',
    instruction: 'Question3,
    options: {
      'a': 'SomeText1',
      'b': 'SomeText2'
    },
    correct: ['b']
  }
]

我有一个数组,其中包含填充此对象并使用 .map() 创建它的必要信息。

const questions = 
[ 'Question1',
  'Question2',
  'Question3'
]

const answers = 
[ 
 'Answer1',
 'Answer2',
 'Answer3'
]

const options = [
   [ 'Option1', 'Option2', 'Option3' ],
   [ 'Option4', 'Option5', 'Option6' ],
   [ 'Option7', 'Option8', 'Option9' ]
 ]

function toJson()
  const alphabet = ['a', 'b', 'c', 'd', 'e'];
  const json = questions.map((question, index) => (
    {
      id: index + 1,
      instruction: question,
      options: Object.assign({}, options[index]),
      correct: answers[index]
    }
  ))
}

我只有options 键有问题。如您所见,我希望将字母作为键,具体取决于问题的答案数量。 当我使用Object.assign() 时,此函数将数字作为键,我不知道如何将它们替换为alphabet 数组中的字母。

编辑:

因此,options 键在所需对象中的解决方案是:

options: Object.assign(
        {}, 
        ...options[index].map((a, i) => ({ [alphabet[i]]: a }))
      ),

现在我可以创建一个带有指定答案的连续字母的对象。

【问题讨论】:

  • 你能告诉我们options变量是什么吗?
  • 添加了 options 变量。内容当然无关紧要。

标签: javascript arrays function object


【解决方案1】:

options[index] 返回一个数组。它包含按索引的值。通过将其传递给Object.assign,您可以通过数组索引将所有值添加为字符串:"0""1" 等。

如果我们首先将map 数组放入{ "a": option } 的列表中,并将结果传播到Object.assign 调用中,我们可以将这些索引更改为您想要的字母:

const questions = 
[ 'Question1',
  'Question2',
  'Question3'
]

const answers = 
[ 
 'Answer1',
 'Answer2',
 'Answer3'
]

const options = [
   [ 'Option1', 'Option2', 'Option3' ],
   [ 'Option4', 'Option5', 'Option6' ],
   [ 'Option7', 'Option8', 'Option9' ]
 ]

function toJson() {
  const alphabet = ['a', 'b', 'c', 'd', 'e'];
  const json = questions.map((question, index) => (
    {
      id: index + 1,
      instruction: question,
      options: Object.assign(
        {}, 
        ...options[index].map((a, i) => ({ [alphabet[i]]: a }))
      ),
      correct: answers[index]
    }
  ));
  
  return json;
}

console.log(toJson());

【讨论】:

    【解决方案2】:

    我建议使用zipobjectFromPairs 之类的东西(都是来自30secondsofcode 的sn-ps,我是一个项目/网站的维护者)。来自网站:

    压缩

    创建一个元素数组,根据原始数组中的位置进行分组。

    使用Math.max.apply() 获取参数中最长的数组。创建一个具有该长度作为返回值的数组,并使用 Array.from() 和一个映射函数来创建一个分组元素数组。如果参数数组的长度不同,则在找不到值的地方使用undefined

    objectFromPairs

    根据给定的键值对创建一个对象。

    使用Array.reduce() 创建和组合键值对。

    我采取的唯一额外步骤是将每个压缩数组修剪为 lengthoptions[index]

    const questions = ['Question1',
      'Question2',
      'Question3'
    ]
    
    const answers = [
      'Answer1',
      'Answer2',
      'Answer3'
    ]
    
    const options = [
      ['Option1', 'Option2', 'Option3'],
      ['Option4', 'Option5', 'Option6'],
      ['Option7', 'Option8', 'Option9']
    ]
    
    const zip = (...arrays) => {
      const maxLength = Math.max(...arrays.map(x => x.length));
      return Array.from({
        length: maxLength
      }).map((_, i) => {
        return Array.from({
          length: arrays.length
        }, (_, k) => arrays[k][i]);
      });
    };
    
    const objectFromPairs = arr => arr.reduce((a, [key, val]) => ((a[key] = val), a), {});
    
    
    function toJson() {
      const alphabet = ['a', 'b', 'c', 'd', 'e'];
      const json = questions.map((question, index) => ({
        id: index + 1,
        instruction: question,
        options: objectFromPairs(zip(alphabet, options[index]).slice(0, options[index].length)),
        correct: answers[index]
      }))
      console.log(json);
    }
    
    toJson();

    【讨论】:

      【解决方案3】:

      以下应该可以工作(我相信)

      options: alphabet.reduce((acc, letter, i) => {
          let option = options[index][i] || 'DefaultText' + i;
          acc[letter] = option;
      
          return acc;
      

      }, {})

      编辑:纠正错别字

      【讨论】:

      • 差不多,因为它除了对象之外还返回一个数组。它还返回字母表中所有字母的选项,即使有 2 或 3 个问题选项。 options: [ [Array], [Array], [Array], a: 'Answer1',
      • 哎呀,这是一个错字options: alphabet.reduce((acc, letter, i) => { let option = options[index][i] || 'DefaultText' + i; acc[letter] = option; return acc; }, {}) 应该可以工作。显然,您的示例中的问题是选项的字母太多,因此如果没有像我所做的那样添加默认值,您将得到未定义
      • 是的,这有点工作。我把信写到e,因为不同的问题可能有不同数量的选项(它不是固定的)。所以在对象中应该有尽可能多的keys作为问题的选项。
      【解决方案4】:

      编辑:

      因此,所需对象中的选项键的解决方案是:

      options: Object.assign(
              {}, 
              ...options[index].map((a, i) => ({ [alphabet[i]]: a }))
            ),
      

      【讨论】:

      • 请解释您的代码为何以及如何解决问题。
      猜你喜欢
      • 1970-01-01
      • 2016-04-28
      • 2020-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多