CopyPastor

Detecting plagiarism made easy.

Score: 1; Reported for: Exact paragraph match Open both answers

Possible Plagiarism

Plagiarized on 2023-05-28
by Nick Parsons

Original Post

Original - Posted on 2020-01-17
by Kamil Kiełczewski



            
Present in both answers; Present only in the new answer; Present only in the old answer;

I wouldn't use `.reduce()` for this. UnderscoreJS has inbuilt methods that already perform what you're trying to do (ie: count the frequencies of items in an array), so you're better of using those instead of reinventing the wheel. What you can use is a combination of JavaScript's `.flatMap()` (annoyingly, underscore doesn't provide it, other libraries like lodash do). And the `_.countBy()` method:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const nflTeams = [{ name: 'Kansas City Chiefs', playersFirstNames: ['Shane', 'Chad', 'Michael', 'Ronald', 'Blake', 'Noah'], champions: true }, { name: 'Philadelphia Eagles', playersFirstNames: ['Jalen', 'Kenneth', 'Boston', 'Trey', 'Jack', 'Andre', 'Jack', 'Lane', 'Jason', 'Nakobe'], champions: false }, { name: 'Cincinnati Bengals', playersFirstNames: ['Brandon', 'Joe', 'Chris', 'Joe', 'Tyler', 'Trenton', 'Trent', 'Mitchell', 'Alex', 'Trey', 'Ted'], champions: false }, { name: 'San Francisco 49ers', playersFirstNames: ['Jimmy', 'Josh', 'Kyle', 'Jordan', 'Brandon', 'Danny', 'George', 'Tyler', 'Charlie', 'Jake', 'Nick', 'Nick', 'Kevin'], champions: false }, ];
const res = _.countBy(nflTeams.flatMap(team => team.playersFirstNames)); console.log(res);
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.6/underscore-min.js" integrity="sha512-2V49R8ndaagCOnwmj8QnbT1Gz/rie17UouD9Re5WxbzRVUGoftCu5IuqqtAM9+UC3fwfHCSJR1hkzNQh/2wdtg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- end snippet -->
If you don't want to use JavaScript's inbuilt `.flatMap()` method you can chain `.map()` and `.flatten()` like you have:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const nflTeams = [{ name: 'Kansas City Chiefs', playersFirstNames: ['Shane', 'Chad', 'Michael', 'Ronald', 'Blake', 'Noah'], champions: true }, { name: 'Philadelphia Eagles', playersFirstNames: ['Jalen', 'Kenneth', 'Boston', 'Trey', 'Jack', 'Andre', 'Jack', 'Lane', 'Jason', 'Nakobe'], champions: false }, { name: 'Cincinnati Bengals', playersFirstNames: ['Brandon', 'Joe', 'Chris', 'Joe', 'Tyler', 'Trenton', 'Trent', 'Mitchell', 'Alex', 'Trey', 'Ted'], champions: false }, { name: 'San Francisco 49ers', playersFirstNames: ['Jimmy', 'Josh', 'Kyle', 'Jordan', 'Brandon', 'Danny', 'George', 'Tyler', 'Charlie', 'Jake', 'Nick', 'Nick', 'Kevin'], champions: false }, ];
const res = _.chain(nflTeams).map(team => team.playersFirstNames).flatten().countBy().value(); console.log(res);
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.6/underscore-min.js" integrity="sha512-2V49R8ndaagCOnwmj8QnbT1Gz/rie17UouD9Re5WxbzRVUGoftCu5IuqqtAM9+UC3fwfHCSJR1hkzNQh/2wdtg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- end snippet -->
---
As for your attempt, I suggest looking into how the core operators of JavaScript work before looking into more complicated concepts like `.reduce()`, which includes `=` (assignment), `!` (negation), `? :` (ternary) etc. In your attempt, you're doing `newObject[firstName] = 1 ?` which assigns the value of `1` to the `firstName` property of your object as well as evaluates to the value of `1`. That means the true portion of your ternary will always be evaluated and will be the thing you're returning. In your case, that's `!newObject[firstName]`. As you just set this to `1`, you're negating it with `!`, and `!1` is `false`. This results in your returning `false`. Then, on the next iteration, `.reduce()` calls your callback with `newObject` set to the `false` value you just returned. It's no longer an object. Again, your code now attempts to set a property `firstName` on `newObject` with `newObject[firstName] = 1`. As this is equivalent to `false[firstName] = 1` it `=` evaluates to `1`, but leaves the `newObject` (ie: `false`) unmodified. When `!newObject[firstName]` runs, it's unable to find the property `firstName` on the `false` value so it ends up returning `!undefined`, ie: `true`. This continues until all your iterations are completed.
As you can see, your current logic in your `.reduce()` callback doesn't make much sense, as you're trying to return a boolea rather than an object, which is what you want your final result to be:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const nflTeams = [{ name: 'Kansas City Chiefs', playersFirstNames: ['Shane', 'Chad', 'Michael', 'Ronald', 'Blake', 'Noah'], champions: true }, { name: 'Philadelphia Eagles', playersFirstNames: ['Jalen', 'Kenneth', 'Boston', 'Trey', 'Jack', 'Andre', 'Jack', 'Lane', 'Jason', 'Nakobe'], champions: false }, { name: 'Cincinnati Bengals', playersFirstNames: ['Brandon', 'Joe', 'Chris', 'Joe', 'Tyler', 'Trenton', 'Trent', 'Mitchell', 'Alex', 'Trey', 'Ted'], champions: false }, { name: 'San Francisco 49ers', playersFirstNames: ['Jimmy', 'Josh', 'Kyle', 'Jordan', 'Brandon', 'Danny', 'George', 'Tyler', 'Charlie', 'Jake', 'Nick', 'Nick', 'Kevin'], champions: false }, ];
const res = _.chain(nflTeams) .map(team => team.playersFirstNames) .flatten() .reduce((currObject, firstName) => { currObject[firstName] = (currObject[firstName] || 0) + 1; return currObject; }, {}) .value(); console.log(res);
<!-- language: lang-html -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.6/underscore-min.js" integrity="sha512-2V49R8ndaagCOnwmj8QnbT1Gz/rie17UouD9Re5WxbzRVUGoftCu5IuqqtAM9+UC3fwfHCSJR1hkzNQh/2wdtg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- end snippet -->

Performance ===========
Today 2023.3.20 I perform tests for chosen solutions on MacOs Monterey 12.1 (M1, 16GB) on Chrome v109, Safari v15.2 and Firefox v110.

Conclusions -----------
* Solutions based on `for-in` (A, L) are fast or fastest on all browsers * Solution based on `JSON.stringify` (B) is slowest on all browsers

[![enter image description here][1]][1]
Details =======
There solutions are presented in the snippet below. If you want to run a performance test on your machine, click * [HERE](https://jsbench.me/qfkqv692c8/1) for empty object * [HERE](https://jsbench.me/uolfgrn0gg) for object witch 10 fields * [HERE](https://jsbench.me/pblfgtco9o/1) for object with 100 fields

Old version of this answer contains tests from 2020 - [HERE](https://stackoverflow.com/revisions/59787784/7).
Links to answers: [A](https://stackoverflow.com/a/785768/860099), [B](https://stackoverflow.com/a/14488421/860099), [C](https://stackoverflow.com/a/785768/860099), [D](https://stackoverflow.com/a/61073221/860099), [E](https://stackoverflow.com/a/19813797/860099), [F](https://stackoverflow.com/a/62976784/860099), G, H, [I](https://stackoverflow.com/a/51061556/860099), [J](https://stackoverflow.com/a/58448172/860099), [K](https://stackoverflow.com/a/10945139/860099), [L](https://stackoverflow.com/a/679937/860099), [M](https://stackoverflow.com/a/55765589/860099), [N](https://stackoverflow.com/a/55765589/860099), [O](https://stackoverflow.com/a/26464582/860099) [P](https://stackoverflow.com/a/4794603/860099) [Q](https://stackoverflow.com/a/5397515/860099)

<!-- begin snippet: js hide: true console: true babel: false -->
<!-- language: lang-js -->
var log = (s, f) => console.log(`${s} --> {}:${f({})} {k:2}:${f({ k: 2 })}`);
function A(obj) { for (var i in obj) return false; return true; }
function B(obj) { return JSON.stringify(obj) === "{}"; }
function C(obj) { return Object.keys(obj).length === 0; }
function D(obj) { return Object.entries(obj).length === 0; }
function E(obj) { return Object.getOwnPropertyNames(obj).length === 0; }
function F(obj) { return Object.keys(obj).length === 0 && obj.constructor === Object; }
function G(obj) { return typeof obj === "undefined" || !Object.keys(obj)[0]; }
function H(obj) { return Object.entries(obj).length === 0 && obj.constructor === Object; }
function I(obj) { return Object.values(obj).every((val) => typeof val === "undefined"); }
function J(obj) { for (const key in obj) { if (hasOwnProperty.call(obj, key)) { return false; } } return true; }
function K(obj) { var isEmpty = true; for (keys in obj) { isEmpty = false; break; } return isEmpty; }
function L(obj) { for (var prop in obj) { if (obj.hasOwnProperty(prop)) return false; } return true; }
function M(obj) { if (obj === null || typeof obj !== 'object' || Object.prototype.toString.call(obj) === '[object Array]') { return false } else { for (var prop in obj) { if (obj.hasOwnProperty(prop)) { return false } } return JSON.stringify(obj) === JSON.stringify({}) } }
function N(obj) { return ( Object.getOwnPropertyNames(obj).length === 0 && Object.getOwnPropertySymbols(obj).length === 0 && Object.getPrototypeOf(obj) === Object.prototype ); }
function O(obj) { return !(Object.getOwnPropertyNames !== undefined ? Object.getOwnPropertyNames(obj).length !== 0 : (function () { for (var key in obj) break; return key !== null && key !== undefined; })()); }
function P(obj) { return $.isEmptyObject(obj) }
function Q(obj) { return _.isEmpty(obj); }
log("A", A); log("B", B); log("C", C); log("D", D); log("E", E); log("F", F); log("G", G); log("H", H); log("I", I); log("J", J); log("K", K); log("L", L); log("M", M); log("N", N); log("O", O); log("P", P); log("Q", Q);

<!-- language: lang-html -->
<script src="https://code.jquery.com/jquery-3.6.4.min.js" integrity="sha256-oP6HI9z1XaZNBrJURtCoUT5SUnxFr8s3BzRl+cbzUq8=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.6/underscore-min.js" integrity="sha512-2V49R8ndaagCOnwmj8QnbT1Gz/rie17UouD9Re5WxbzRVUGoftCu5IuqqtAM9+UC3fwfHCSJR1hkzNQh/2wdtg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- end snippet -->
[![enter image description here][2]][2]

[1]: https://i.stack.imgur.com/ITeDZ.png [2]: https://i.stack.imgur.com/JO8Le.png

        
Present in both answers; Present only in the new answer; Present only in the old answer;