【问题标题】:Array to Object es6 javascript数组到对象 es6 javascript
【发布时间】:2016-10-13 09:56:37
【问题描述】:

我正在尝试查看在 es6 中是否有更小的方法可以将数组转换为对象。 (我不用担心跨浏览器)

我目前有:

function (values) // values being an array.
{   
    let [videos, video_count, page] = values;
    let data = { videos, video_count, page };
    someFunctions(data);
    moreFunctions(data);
}

但我想知道是否可以删除函数的第一行 let [videos....] 部分。并以某种方式 inline 进行转换。

我已经阅读了mozilla: Destructuring assignment,但在那里我看不到它。 (但我可能理解错了)而且我真的不够聪明,无法理解ECMA: ES6 Spec

我怀疑这是不可能的,上面已经是我能做到的最简单的了。 但是,如果我可以不创建 videosvideo_countpage tmp 变量,我会更快乐。

【问题讨论】:

  • 总是可以用老式的方式来做:var data = {videos:values[0], video_count:values[1], page:values[2]};
  • 这是我考虑过的,但想看看是否有es6的方式。似乎有一种方法可以做几乎所有我想做的事情,我想我找到了一个更小众的用例。
  • 好吧,无论哪种方式,您都必须为您的属性值命名,它们不会凭空出现。

标签: javascript ecmascript-6 destructuring


【解决方案1】:

你可以直接在函数参数中解构

function myFunc([ videos, video_count, page ])
{   
    let data = { videos, video_count, page };
    someFunctions(data);
    moreFunctions(data);
}

myFunc(values);

我使用这种技术做了很多数据抽象

// basic abstraction
const ratio = (n, d) => ({n, d});
const numer = ({n}) => n;
const denom = ({d}) => d;

// compound abstraction using selectors
const ratioAdd = (x,y) => ratio(
  numer(x) * denom(y) + numer(y) * denom(x),
  denom(x) * denom(y)
);

// or skip selectors if you're feeling lazy
const printRatio = ({n,d}) => `${n}/${d}`;

console.log(printRatio(ratioAdd(ratio(1,3), ratio(1,4)))); //= 7/12

您似乎一心想以某种方式缩短代码,所以就这样吧。在这种情况下,“让它变短”意味着先让它变长。

// Goal:
obuild(keys,values) //=> ourObject

通用过程zipassignobuild 应该可以满足我们的需求。这大大优于@CodingIntigue 的答案,因为它不是一个试图完成所有任务的大功能。将它们分开意味着降低复杂性,并提高可读性和可重用性。

// zip :: [a] -> [b] -> [[a,b]]
const zip = ([x,...xs], [y,...ys]) => {
  if (x === undefined || y === undefined)
    return [];
  else
    return [[x,y], ...zip(xs,ys)];
}

// assign :: (Object{k:v}, [k,v]) -> Object{k:v}
const assign = (o, [k,v]) => Object.assign(o, {[k]: v});

// obuild :: ([k], [v]) -> Object{k:v}
const obuild = (keys, values) => zip(keys, values).reduce(assign, {});

let keys = ['a', 'b', 'c'];
let values = [1, 2, 3];

console.log(obuild(keys,values));
// { 'a': 1, 'b': 2, 'c': 3 }

【讨论】:

  • 这仍然以 tmp 变量结束?虽然values 现在已经消失了,但我主要试图删除的三个仍然存在。
  • 这大大优于@CodingIntigue 的答案 - 哎哟。不过,您并没有错,更具可读性。
  • @CodingIntrigue 我真的没有恶意;我正在处理一项非常烦人的任务,否则我可能会用更委婉的措辞。
  • @naomik 无意冒犯,这不是错误的陈述!
  • @naomik 仅供参考,我最后在函数参数中进行了解构。它看起来是迄今为止最整洁的。非常感谢。
【解决方案2】:

使用给定的属性和名称,这可能是实现所需结果的最短方法。

但是,如果您有更多字段,您可以使用reduce 来避免重复。虽然它不像解构那样可读:

let data = values.reduce((prev, val, index) => Object.assign(prev, {[["videos", "video_count", "page"][index]]: val} ), {});

然后您可以将其抽象为通用函数:

const values = ["test1","test2","test3"];
const mapArrayToObject = (array, fields) =>
  array.reduce(
    (prev, val, index) => Object.assign(prev, { [fields[index]]: val } ),
    {}
  );
const data = mapArrayToObject(values, ["videos", "video_count", "page"]);
console.log(data);

【讨论】:

    猜你喜欢
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2018-09-15
    • 2017-09-19
    • 2021-03-03
    相关资源
    最近更新 更多