te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>Javascript seperating array of objects into multiple arrays using map(), and Iterator - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript seperating array of objects into multiple arrays using map(), and Iterator - Stack Overflow

programmeradmin2浏览0评论
  1. Basically I have an array of objects like

    var array = [{x: 10, y: 5, r: 10, ...} ]

There are more fields in the object, but to the point, this is the way I've found to seperate the fields to arrays:

var x = array.map(obj => obj.x);
var y = array.map(obj => obj.y);
// and so on for each field

Works, but seems very inefficient as the number of fields and the array size grows, as this scans the array multiple times. I could use a standard loop, but I do prefer the map() as I think it is more readable in this case. Is it possible to return multiple values from map? I think something like:

var [x, y] = array.map(obj => [obj.x, obj.y]); // should output two arrays

Or anything similar which will be readable (reduce is less readable IMO).

  1. I did notice some newer javascript functions like array.entries() which return an iterator object. How can I implement such functions?
  1. Basically I have an array of objects like

    var array = [{x: 10, y: 5, r: 10, ...} ]

There are more fields in the object, but to the point, this is the way I've found to seperate the fields to arrays:

var x = array.map(obj => obj.x);
var y = array.map(obj => obj.y);
// and so on for each field

Works, but seems very inefficient as the number of fields and the array size grows, as this scans the array multiple times. I could use a standard loop, but I do prefer the map() as I think it is more readable in this case. Is it possible to return multiple values from map? I think something like:

var [x, y] = array.map(obj => [obj.x, obj.y]); // should output two arrays

Or anything similar which will be readable (reduce is less readable IMO).

  1. I did notice some newer javascript functions like array.entries() which return an iterator object. How can I implement such functions?
Share Improve this question edited Jan 2, 2019 at 21:32 user3599803 asked Jan 2, 2019 at 18:06 user3599803user3599803 7,03421 gold badges77 silver badges137 bronze badges 1
  • Do all the objects contain the same keys? – ibrahim mahrir Commented Jan 2, 2019 at 18:16
Add a ment  | 

3 Answers 3

Reset to default 7

You could reduce the array and iterate the objects key/value pairs. Then push the values to the array of the given property.

var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }],
    result = array.reduce((r, o) => {
        Object.entries(o).forEach(([k, v]) => (r[k] = r[k] || []).push(v));
        return r;
    }, Object.create(null));
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

So, you were on to the right start with your second attempt:

var [x, y] = array.map(obj => [obj.x, obj.y]);

As you indicate, the first attempt is too inefficient, since you will have to loop through the array multiple times for each field you want to pull out, but you can do everything you want to do using an array's .reduce() method.

I would do the following:

var [x, y] = array.reduce(
    (accum, val) => {
        accum[0].push(val.x);
        accum[1].push(val.y);
        return accum;
    },
    [ [], [] ]
);

What I'm doing is telling the reducer to initialize the accumulator with an empty array of arrays ([ [], [] ]), and when it loops through the array, it will put the .x properties into the first array in the accumulator and the .y properties into the second array. And thanks to destructuring, x will be an array of all the .x properties and y will be an array of all the .y properties.

This approach is easy to extend as your fields grow by adding more empty arrays to the initial accumulator object and making sure in the reducer to push those fields into that new object.

If all the objects have the same keys, you could get a copy of those keys and cache so you won't need to get them for every object. You can then use those keys to initialize the result object, then loop the array and push the values into the arrays, like so:

var keys = Object.keys(array[0]);                          // get the keys of the first object (assuming all objects have the same keys)
var result = {};                                           // the result object (you can use the safe Object.create(null) instead of {})

keys.forEach(key => result[key] = []);                     // initialize the result object (make an empty array entry for each key in keys)

array.forEach(obj =>                                       // for each object in array
  keys.forEach(key => result[key].push(obj[key]))          // add the values of this object to their corresponding array from result using keys from the array keys
);

Demo:

var array = [{ x: 10, y: 5, r: 10 }, { x: 11, y: 6, r: 11 }];

var keys = Object.keys(array[0]);
var result = {};

keys.forEach(key => result[key] = []);

array.forEach(obj =>
  keys.forEach(key => result[key].push(obj[key]))
);
    
console.log(result);

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论